]> O.S.I.I.S - jp/crow.git/commitdiff
getStremFromPath made instanced for overriding in designiface, crowide wip
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sat, 10 Mar 2018 05:03:25 +0000 (06:03 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sat, 10 Mar 2018 05:03:25 +0000 (06:03 +0100)
69 files changed:
CrowIDE/CrowIDE.csproj
CrowIDE/icons/compile.svg
CrowIDE/src/CrowIDE.cs
CrowIDE/src/DesignInterface.cs
CrowIDE/src/EditPane.cs [deleted file]
CrowIDE/src/Editor.cs [deleted file]
CrowIDE/src/Editors/CodeBuffer/CodeBuffer.cs [new file with mode: 0644]
CrowIDE/src/Editors/CodeBuffer/CodeBufferEventArgs.cs [new file with mode: 0644]
CrowIDE/src/Editors/CodeBuffer/CodeLine.cs [new file with mode: 0644]
CrowIDE/src/Editors/CodeBuffer/Node.cs [new file with mode: 0644]
CrowIDE/src/Editors/CodeBuffer/SourceEditor.cs [new file with mode: 0644]
CrowIDE/src/Editors/CodeBuffer/TextFormatting.cs [new file with mode: 0644]
CrowIDE/src/Editors/CodeBuffer/Token.cs [new file with mode: 0644]
CrowIDE/src/Editors/EditPane.cs [new file with mode: 0644]
CrowIDE/src/Editors/Editor.cs [new file with mode: 0644]
CrowIDE/src/Editors/ImlVisualEditor.cs [new file with mode: 0644]
CrowIDE/src/Editors/Parsers/BufferParser.cs [new file with mode: 0644]
CrowIDE/src/Editors/Parsers/CSharpParser.cs [new file with mode: 0644]
CrowIDE/src/Editors/Parsers/StyleParser.cs [new file with mode: 0644]
CrowIDE/src/Editors/Parsers/XMLParser.cs [new file with mode: 0644]
CrowIDE/src/Editors/SvgEditor.cs [new file with mode: 0644]
CrowIDE/src/Extensions.cs
CrowIDE/src/GraphicObjectDesignContainer.cs
CrowIDE/src/ImlVisualEditor.cs [deleted file]
CrowIDE/src/ProjectNodes.cs
CrowIDE/src/Solution.cs
CrowIDE/src/SourceEditor/BufferParser.cs [deleted file]
CrowIDE/src/SourceEditor/CSharpParser.cs [deleted file]
CrowIDE/src/SourceEditor/CodeBuffer.cs [deleted file]
CrowIDE/src/SourceEditor/CodeBufferEventArgs.cs [deleted file]
CrowIDE/src/SourceEditor/CodeLine.cs [deleted file]
CrowIDE/src/SourceEditor/Node.cs [deleted file]
CrowIDE/src/SourceEditor/SourceEditor.cs [deleted file]
CrowIDE/src/SourceEditor/StyleParser.cs [deleted file]
CrowIDE/src/SourceEditor/TextFormatting.cs [deleted file]
CrowIDE/src/SourceEditor/Token.cs [deleted file]
CrowIDE/src/SourceEditor/XMLParser.cs [deleted file]
CrowIDE/src/SvgEditor.cs [deleted file]
CrowIDE/ui/ContextMenu.template [new file with mode: 0644]
CrowIDE/ui/CrowIDE.crow
CrowIDE/ui/DockWindows/winToolbox.crow
CrowIDE/ui/EditPane.template [deleted file]
CrowIDE/ui/EditPaneItems.template [deleted file]
CrowIDE/ui/GTreeExpITemp.crow
CrowIDE/ui/GTreeExplorer.crow
CrowIDE/ui/IMLEdit.itemp [deleted file]
CrowIDE/ui/SourceEditor.crow [deleted file]
CrowIDE/ui/SrcEdit.itemp [deleted file]
CrowIDE/ui/editors/EditPane.template [new file with mode: 0644]
CrowIDE/ui/editors/EditPaneItems.template [new file with mode: 0644]
CrowIDE/ui/editors/IMLEdit.itemp [new file with mode: 0644]
CrowIDE/ui/editors/SourceEditor.crow [new file with mode: 0644]
CrowIDE/ui/editors/SrcEdit.itemp [new file with mode: 0644]
CrowIDE/ui/editors/SvgEdit.itemp [new file with mode: 0644]
Tests/OpenGL/Shader.cs
Tests/OpenGL/Texture.cs
src/BmpPicture.cs
src/CompilerServices/CompilerServices.cs
src/ExtensionsMethods.cs
src/GraphicObjects/GraphicObject.cs
src/GraphicObjects/Group.cs
src/GraphicObjects/Image.cs
src/GraphicObjects/TabItem.cs
src/IML/IMLContext.cs
src/Instantiator.cs
src/Interface.cs
src/Picture.cs
src/SvgPicture.cs
src/XCursor.cs

index 4f48ad0eda19d19f9dbc17872ee73701ac4e0a9e..399e0d99c00670a0e067a44c31d92f51e416ba9b 100644 (file)
@@ -70,7 +70,6 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="src\CrowIDE.cs" />
-    <Compile Include="src\ImlVisualEditor.cs" />
     <Compile Include="src\Extensions.cs" />
     <Compile Include="src\Solution.cs" />
     <Compile Include="src\Project.cs" />
       <Link>src\InterfaceControler.cs</Link>
     </Compile>
     <Compile Include="src\DesignInterface.cs" />
-    <Compile Include="src\EditPane.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\SourceEditor.cs" />
-    <Compile Include="src\SourceEditor\TextFormatting.cs" />
-    <Compile Include="src\SourceEditor\Token.cs" />
-    <Compile Include="src\SourceEditor\XMLParser.cs" />
-    <Compile Include="src\SourceEditor\StyleParser.cs" />
-    <Compile Include="src\SourceEditor\BufferParser.cs" />
     <Compile Include="src\MemberView\MembersView.cs" />
     <Compile Include="src\MemberView\PropertyContainer.cs" />
     <Compile Include="src\MemberView\CategoryContainer.cs" />
     <Compile Include="src\GraphicObjectDesignContainer.cs" />
-    <Compile Include="src\Editor.cs" />
-    <Compile Include="src\SvgEditor.cs" />
+    <Compile Include="src\Editors\Editor.cs" />
+    <Compile Include="src\Editors\EditPane.cs" />
+    <Compile Include="src\Editors\ImlVisualEditor.cs" />
+    <Compile Include="src\Editors\SvgEditor.cs" />
+    <Compile Include="src\Editors\Parsers\BufferParser.cs" />
+    <Compile Include="src\Editors\Parsers\CSharpParser.cs" />
+    <Compile Include="src\Editors\Parsers\StyleParser.cs" />
+    <Compile Include="src\Editors\Parsers\XMLParser.cs" />
+    <Compile Include="src\Editors\CodeBuffer\CodeBuffer.cs" />
+    <Compile Include="src\Editors\CodeBuffer\CodeBufferEventArgs.cs" />
+    <Compile Include="src\Editors\CodeBuffer\CodeLine.cs" />
+    <Compile Include="src\Editors\CodeBuffer\Node.cs" />
+    <Compile Include="src\Editors\CodeBuffer\SourceEditor.cs" />
+    <Compile Include="src\Editors\CodeBuffer\TextFormatting.cs" />
+    <Compile Include="src\Editors\CodeBuffer\Token.cs" />
   </ItemGroup>
   <ItemGroup>
     <Folder Include="ui\" />
     <Folder Include="src\" />
     <Folder Include="images\" />
-    <Folder Include="src\SourceEditor\" />
     <Folder Include="ui\ItemTemplates\" />
     <Folder Include="src\MemberView\" />
     <Folder Include="ui\DockWindows\" />
+    <Folder Include="ui\editors\" />
+    <Folder Include="src\Editors\" />
+    <Folder Include="src\Editors\Parsers\" />
+    <Folder Include="src\Editors\CodeBuffer\" />
   </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="images\save.svg" />
       <LogicalName>Crow.TreeExpandable.template</LogicalName>
     </EmbeddedResource>
     <EmbeddedResource Include="ui\ProjectTree.template" />
-    <EmbeddedResource Include="ui\EditPane.template">
-      <LogicalName>Crow.Coding.EditPane.template</LogicalName>
-    </EmbeddedResource>
-    <EmbeddedResource Include="ui\EditPaneItems.template" />
     <EmbeddedResource Include="ui\CrowIDE.crow" />
     <EmbeddedResource Include="ui\icons\blank-file.svg" />
     <EmbeddedResource Include="ui\icons\sign-out.svg" />
       <LogicalName>Crow.MenuItem.template</LogicalName>
     </EmbeddedResource>
     <EmbeddedResource Include="ui\Options.crow" />
-    <EmbeddedResource Include="ui\IMLEdit.itemp" />
-    <EmbeddedResource Include="ui\SrcEdit.itemp" />
     <EmbeddedResource Include="ui\IcoBut.template" />
     <EmbeddedResource Include="ui\MembersItem.template" />
     <EmbeddedResource Include="ui\ItemTemplates\Enum.template" />
     <EmbeddedResource Include="icons\text-file.svg" />
     <EmbeddedResource Include="icons\undo.svg" />
     <EmbeddedResource Include="icons\redo.svg" />
-    <EmbeddedResource Include="ui\SourceEditor.crow" />
+    <EmbeddedResource Include="ui\ContextMenu.template">
+      <LogicalName>Crow.ContextMenu.template</LogicalName>
+    </EmbeddedResource>
+    <EmbeddedResource Include="ui\editors\EditPane.template">
+      <LogicalName>Crow.Coding.EditPane.template</LogicalName>
+    </EmbeddedResource>
+    <EmbeddedResource Include="ui\editors\EditPaneItems.template">
+      <LogicalName>Crow.Coding.ui.EditPaneItems.template</LogicalName>
+    </EmbeddedResource>
+    <EmbeddedResource Include="ui\editors\IMLEdit.itemp">
+      <LogicalName>Crow.Coding.ui.IMLEdit.itemp</LogicalName>
+    </EmbeddedResource>
+    <EmbeddedResource Include="ui\editors\SourceEditor.crow">
+      <LogicalName>Crow.Coding.ui.SourceEditor.crow</LogicalName>
+    </EmbeddedResource>
+    <EmbeddedResource Include="ui\editors\SrcEdit.itemp">
+      <LogicalName>Crow.Coding.ui.SrcEdit.itemp</LogicalName>
+    </EmbeddedResource>
+    <EmbeddedResource Include="ui\editors\SvgEdit.itemp">
+      <LogicalName>Crow.Coding.ui.SvgEdit.itemp</LogicalName>
+    </EmbeddedResource>
   </ItemGroup>
   <ItemGroup>
     <None Include="ui\test.crow">
index 3f6ed2bed2ae484de8a7263eea48c5dd5403a90a..c1a14e77d6a14943dd83fd65bbbed4aa04d9c497 100644 (file)
@@ -2,8 +2,8 @@
 <!-- Generated by IcoMoon.io -->
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
-<path fill="#444444" d="M12 7v-2l-1.2-0.4c-0.1-0.3-0.2-0.7-0.4-1l0.6-1.2-1.5-1.3-1.1 0.5c-0.3-0.2-0.6-0.3-1-0.4l-0.4-1.2h-2l-0.4 1.2c-0.3 0.1-0.7 0.2-1 0.4l-1.1-0.5-1.4 1.4 0.6 1.2c-0.2 0.3-0.3 0.6-0.4 1l-1.3 0.3v2l1.2 0.4c0.1 0.3 0.2 0.7 0.4 1l-0.5 1.1 1.4 1.4 1.2-0.6c0.3 0.2 0.6 0.3 1 0.4l0.3 1.3h2l0.4-1.2c0.3-0.1 0.7-0.2 1-0.4l1.2 0.6 1.4-1.4-0.6-1.2c0.2-0.3 0.3-0.6 0.4-1l1.2-0.4zM3 6c0-1.7 1.3-3 3-3s3 1.3 3 3c0 1.7-1.3 3-3 3s-3-1.3-3-3z"></path>
-<path fill="#444444" d="M7.5 6c0 0.828-0.672 1.5-1.5 1.5s-1.5-0.672-1.5-1.5c0-0.828 0.672-1.5 1.5-1.5s1.5 0.672 1.5 1.5z"></path>
-<path fill="#444444" d="M16 3v-1h-0.6c0-0.2-0.1-0.4-0.2-0.5l0.4-0.4-0.7-0.7-0.4 0.4c-0.2-0.1-0.3-0.2-0.5-0.2v-0.6h-1v0.6c-0.2 0-0.4 0.1-0.5 0.2l-0.4-0.4-0.7 0.7 0.4 0.4c-0.1 0.2-0.2 0.3-0.2 0.5h-0.6v1h0.6c0 0.2 0.1 0.4 0.2 0.5l-0.4 0.4 0.7 0.7 0.4-0.4c0.2 0.1 0.3 0.2 0.5 0.2v0.6h1v-0.6c0.2 0 0.4-0.1 0.5-0.2l0.4 0.4 0.7-0.7-0.4-0.4c0.1-0.2 0.2-0.3 0.2-0.5h0.6zM13.5 3.5c-0.6 0-1-0.4-1-1s0.4-1 1-1 1 0.4 1 1c0 0.6-0.4 1-1 1z"></path>
-<path fill="#444444" d="M15.4 11.8c-0.1-0.3-0.2-0.6-0.4-0.9l0.3-0.6-0.7-0.7-0.5 0.4c-0.3-0.2-0.6-0.3-0.9-0.4l-0.2-0.6h-1l-0.2 0.6c-0.3 0.1-0.6 0.2-0.9 0.4l-0.6-0.3-0.7 0.7 0.3 0.6c-0.2 0.3-0.3 0.6-0.4 0.9l-0.5 0.1v1l0.6 0.2c0.1 0.3 0.2 0.6 0.4 0.9l-0.3 0.6 0.7 0.7 0.6-0.3c0.3 0.2 0.6 0.3 0.9 0.4l0.1 0.5h1l0.2-0.6c0.3-0.1 0.6-0.2 0.9-0.4l0.6 0.3 0.7-0.7-0.4-0.5c0.2-0.3 0.3-0.6 0.4-0.9l0.6-0.2v-1l-0.6-0.2zM12.5 14c-0.8 0-1.5-0.7-1.5-1.5s0.7-1.5 1.5-1.5 1.5 0.7 1.5 1.5-0.7 1.5-1.5 1.5z"></path>
+<path fill="#FFFFFF" d="M12 7v-2l-1.2-0.4c-0.1-0.3-0.2-0.7-0.4-1l0.6-1.2-1.5-1.3-1.1 0.5c-0.3-0.2-0.6-0.3-1-0.4l-0.4-1.2h-2l-0.4 1.2c-0.3 0.1-0.7 0.2-1 0.4l-1.1-0.5-1.4 1.4 0.6 1.2c-0.2 0.3-0.3 0.6-0.4 1l-1.3 0.3v2l1.2 0.4c0.1 0.3 0.2 0.7 0.4 1l-0.5 1.1 1.4 1.4 1.2-0.6c0.3 0.2 0.6 0.3 1 0.4l0.3 1.3h2l0.4-1.2c0.3-0.1 0.7-0.2 1-0.4l1.2 0.6 1.4-1.4-0.6-1.2c0.2-0.3 0.3-0.6 0.4-1l1.2-0.4zM3 6c0-1.7 1.3-3 3-3s3 1.3 3 3c0 1.7-1.3 3-3 3s-3-1.3-3-3z"></path>
+<path fill="#FFFFFF" d="M7.5 6c0 0.828-0.672 1.5-1.5 1.5s-1.5-0.672-1.5-1.5c0-0.828 0.672-1.5 1.5-1.5s1.5 0.672 1.5 1.5z"></path>
+<path fill="#FFFFFF" d="M16 3v-1h-0.6c0-0.2-0.1-0.4-0.2-0.5l0.4-0.4-0.7-0.7-0.4 0.4c-0.2-0.1-0.3-0.2-0.5-0.2v-0.6h-1v0.6c-0.2 0-0.4 0.1-0.5 0.2l-0.4-0.4-0.7 0.7 0.4 0.4c-0.1 0.2-0.2 0.3-0.2 0.5h-0.6v1h0.6c0 0.2 0.1 0.4 0.2 0.5l-0.4 0.4 0.7 0.7 0.4-0.4c0.2 0.1 0.3 0.2 0.5 0.2v0.6h1v-0.6c0.2 0 0.4-0.1 0.5-0.2l0.4 0.4 0.7-0.7-0.4-0.4c0.1-0.2 0.2-0.3 0.2-0.5h0.6zM13.5 3.5c-0.6 0-1-0.4-1-1s0.4-1 1-1 1 0.4 1 1c0 0.6-0.4 1-1 1z"></path>
+<path fill="#FFFFFF" d="M15.4 11.8c-0.1-0.3-0.2-0.6-0.4-0.9l0.3-0.6-0.7-0.7-0.5 0.4c-0.3-0.2-0.6-0.3-0.9-0.4l-0.2-0.6h-1l-0.2 0.6c-0.3 0.1-0.6 0.2-0.9 0.4l-0.6-0.3-0.7 0.7 0.3 0.6c-0.2 0.3-0.3 0.6-0.4 0.9l-0.5 0.1v1l0.6 0.2c0.1 0.3 0.2 0.6 0.4 0.9l-0.3 0.6 0.7 0.7 0.6-0.3c0.3 0.2 0.6 0.3 0.9 0.4l0.1 0.5h1l0.2-0.6c0.3-0.1 0.6-0.2 0.9-0.4l0.6 0.3 0.7-0.7-0.4-0.5c0.2-0.3 0.3-0.6 0.4-0.9l0.6-0.2v-1l-0.6-0.2zM12.5 14c-0.8 0-1.5-0.7-1.5-1.5s0.7-1.5 1.5-1.5 1.5 0.7 1.5 1.5-0.7 1.5-1.5 1.5z"></path>
 </svg>
index a5e8c249390ded3f7a9198ca68ccf285feb9a2e5..588700b83ffe6a16f00be7ff27381777b1fa934a 100644 (file)
@@ -38,7 +38,7 @@ namespace Crow.Coding
 {
        class CrowIDE : CrowWindow
        {
-               public Command CMDNew, CMDOpen, CMDSave, CMDSaveAs, CMDQuit,
+               public Command CMDNew, CMDOpen, CMDSave, CMDSaveAs, cmdCloseSolution, CMDQuit,
                CMDUndo, CMDRedo, CMDCut, CMDCopy, CMDPaste, CMDHelp,
                CMDAbout, CMDOptions,
                CMDViewGTExp, CMDViewProps, CMDViewProj, CMDViewProjProps, CMDViewErrors, CMDViewSolution, CMDViewEditor, CMDViewProperties,
@@ -59,6 +59,8 @@ namespace Crow.Coding
                        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")};
 
+                       cmdCloseSolution = new Command(new Action(() => closeSolution())) { Caption = "Close Solution", Icon = new SvgPicture("#Crow.Coding.ui.icons.paste-on-document.svg"), CanExecute = true};
+
                        CMDViewErrors = new Command(new Action(() => loadDockWindow ("#Crow.Coding.ui.DockWindows.winErrors.crow")))
                        { Caption = "Errors pane"};
                        CMDViewSolution = new Command(new Action(() => loadDockWindow ("#Crow.Coding.ui.DockWindows.winSolution.crow")))
@@ -70,7 +72,7 @@ namespace Crow.Coding
                        CMDViewToolbox = new Command(new Action(() => loadDockWindow ("#Crow.Coding.ui.DockWindows.winToolbox.crow")))
                        { Caption = "Toolbox"};
 
-                       CMDViewGTExp = new Command(new Action(() => loadWindow ("#Crow.Coding.ui.GTreeExplorer.crow"))) { Caption = "Graphic Tree Explorer"};
+                       CMDViewGTExp = new Command(new Action(() => loadDockWindow ("#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 ("#Crow.Coding.ui.CSProjExplorer.crow"))) { Caption = "Project Explorer"};
@@ -85,7 +87,11 @@ namespace Crow.Coding
                void saveFileDialog() {}
                void undo() {}
                void redo() {}
-
+               void closeSolution (){
+                       if (currentSolution != null)
+                               currentSolution.CloseSolution ();
+                       CurrentSolution = null;
+               }
 
                [STAThread]
                static void Main ()
@@ -166,7 +172,9 @@ namespace Crow.Coding
                                if (currentSolution == value)
                                        return;
                                currentSolution = value;
-                               NotifyValueChanged ("CurrentSolution", currentSolution);
+                               lock (MainIFace) {
+                                       NotifyValueChanged ("CurrentSolution", currentSolution);
+                               }
                        }
                }
 
index 3c1abf016665119c9752c47f736401ad3ebcf9ae..4178e39847bbbadf50307a2c19b3575cfc08f7ea 100644 (file)
@@ -29,6 +29,7 @@ using System.Globalization;
 using System.Threading;
 using System.Collections.Generic;
 using System.Diagnostics;
+using System.IO;
 
 namespace Crow.Coding
 {
@@ -80,6 +81,16 @@ namespace Crow.Coding
                        System.Diagnostics.Debugger.Break ();
                        return null;
                }
+               public override System.IO.Stream GetStreamFromPath (string path)
+               {
+                       ProjectFile pi;
+                       if (ProjFile.Project.solution.GetProjectFileFromPath (path, out pi)) {
+                               return new FileStream (pi.AbsolutePath, FileMode.Open); 
+                       }
+                       
+                       Console.WriteLine ("File not found: {0}", path);
+                       return null;
+               }
                public override bool ProcessMouseMove (int x, int y)
                {
                        int deltaX = x - Mouse.X;
@@ -171,7 +182,7 @@ namespace Crow.Coding
                                LayoutingQueueItem lqi;
                                while (LayoutingQueue.Count > 0) {
                                        lqi = LayoutingQueue.Dequeue ();
-                                       Console.WriteLine (lqi.ToString ());
+                                       //Console.WriteLine (lqi.ToString ());
                                        #if DEBUG_LAYOUTING
                                        currentLQI = lqi;
                                        curLQIsTries.Add(currentLQI);
diff --git a/CrowIDE/src/EditPane.cs b/CrowIDE/src/EditPane.cs
deleted file mode 100644 (file)
index a75522f..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-// EditPane.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 Crow;
-using System.Linq;
-
-namespace Crow.Coding
-{
-       public class EditPane : TemplatedGroup
-       {
-               public EditPane () {}
-
-               object selectedItemElement = null;
-
-               public override int SelectedIndex {
-                       get {
-                               return base.SelectedIndex;
-                       }
-                       set {
-                               base.SelectedIndex = value;
-                       }
-               }
-               public object SelectedItemElement {
-                       get { return selectedItemElement; }
-                       set {
-                               if (selectedItemElement == value)
-                                       return;
-                               selectedItemElement = value;
-                               NotifyValueChanged ("SelectedItemElement", selectedItemElement);
-                       }
-               }
-       }
-}
-
diff --git a/CrowIDE/src/Editor.cs b/CrowIDE/src/Editor.cs
deleted file mode 100644 (file)
index 41aa606..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-//
-// Editor.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.Threading;
-using System.Xml.Serialization;
-
-namespace Crow.Coding
-{
-       public abstract class Editor : ScrollingObject
-       {
-               #region CTOR
-               protected Editor ():base(){
-                       Thread t = new Thread (backgroundThreadFunc);
-                       t.IsBackground = true;
-                       t.Start ();
-               }
-               #endregion
-
-               protected ReaderWriterLockSlim editorMutex = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
-               protected ProjectFile projFile = null;
-               Exception error = null;
-
-               public virtual ProjectFile ProjectNode
-               {
-                       get { return projFile; }
-                       set
-                       {
-                               if (projFile == value)
-                                       return;
-
-                               if (projFile != null)
-                                       projFile.UnregisterEditor (this);
-
-                               projFile = value;
-
-                               if (projFile != null)                                   
-                                       projFile.RegisterEditor (this);
-
-                               NotifyValueChanged ("ProjectNode", projFile);
-                       }
-               }
-               [XmlIgnore]public Exception Error {
-                       get { return error; }
-                       set {
-                               if (error == value)
-                                       return;
-                               error = value;
-                               NotifyValueChanged ("Error", error);
-                               NotifyValueChanged ("HasError", HasError);
-                       }
-               }
-               [XmlIgnore]public bool HasError {
-                       get { return error != null; }
-               }
-
-               protected abstract void updateEditorFromProjFile ();
-               protected abstract void updateProjFileFromEditor ();
-               protected abstract bool EditorIsDirty { get; set; }
-               protected virtual bool IsReady { get { return true; }}
-               protected virtual void updateCheckPostProcess () {}
-
-               protected void backgroundThreadFunc () {
-                       while (true) {
-                               if (IsReady) {
-                                       if (projFile != null) {
-                                               if (!projFile.RegisteredEditors [this]) {
-                                                       projFile.RegisteredEditors [this] = true;
-                                                       updateEditorFromProjFile ();
-                                               } else if (EditorIsDirty) {
-                                                       EditorIsDirty = false;
-                                                       updateProjFileFromEditor ();
-                                               }
-                                               updateCheckPostProcess ();
-                                       }
-                               }
-                               Thread.Sleep (50);
-                       }       
-               }
-       }
-}
-
diff --git a/CrowIDE/src/Editors/CodeBuffer/CodeBuffer.cs b/CrowIDE/src/Editors/CodeBuffer/CodeBuffer.cs
new file mode 100644 (file)
index 0000000..13c422a
--- /dev/null
@@ -0,0 +1,528 @@
+//
+//  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;
+using System.Threading;
+
+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 ReaderWriterLockSlim editMutex = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
+
+               //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
+
+               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;
+                               editMutex.EnterWriteLock ();
+                               lines [i] = value;
+                               editMutex.ExitWriteLock ();
+                               LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
+                       }
+               }
+
+               public void RemoveAt(int i){
+                       editMutex.EnterWriteLock ();
+                       lines.RemoveAt (i);
+                       editMutex.ExitWriteLock ();
+                       LineRemoveEvent.Raise (this, new CodeBufferEventArgs (i));
+               }
+               public void Insert(int i, string item){
+                       editMutex.EnterWriteLock ();
+                       lines.Insert (i, item);
+                       editMutex.ExitWriteLock ();
+                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (i));
+               }
+               public void Add(CodeLine item){
+                       editMutex.EnterWriteLock ();
+                       lines.Add (item);
+                       editMutex.ExitWriteLock ();
+                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (lines.Count - 1));
+               }
+               public void AddRange (string[] items){
+                       int start = lines.Count;
+                       editMutex.EnterWriteLock ();
+                       for (int i = 0; i < items.Length; i++)
+                               lines.Add (items [i]);
+                       editMutex.ExitWriteLock ();
+                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length));
+               }
+               public void AddRange (CodeLine[] items){
+                       int start = lines.Count;
+                       editMutex.EnterWriteLock ();
+                       lines.AddRange (items);
+                       editMutex.ExitWriteLock ();
+                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length));
+               }
+               public void Clear () {
+                       editMutex.EnterWriteLock ();
+                       longestLineCharCount = 0;
+                       lines.Clear ();
+                       editMutex.ExitWriteLock ();
+                       BufferCleared.Raise (this, null);
+               }
+               public void UpdateLine(int i, string newContent){
+                       editMutex.EnterWriteLock ();
+                       this [i].Content = newContent;
+                       editMutex.ExitWriteLock ();
+                       LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
+               }
+               public void AppenedLine(int i, string newContent){
+                       editMutex.EnterWriteLock ();
+                       this [i].Content += newContent;
+                       editMutex.ExitWriteLock ();
+                       LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
+               }
+               public void RemoveLeadingTab (int l) {
+                       if (this [l] [0] == '\t') {
+                               UpdateLine (l, this [l].Content.Substring (1));
+                               return;
+                       }
+                       int i = 0;
+                       while (i < Interface.TabSize) {
+                               if (this [l] [i] != ' ')
+                                       break;
+                               i++;
+                       }
+                       if (i > 0)
+                               UpdateLine (l, this [l].Content.Substring (i));
+               }
+               public void ToogleFolding (int line) {
+                       if (!this [line].IsFoldable)
+                               return;
+                       editMutex.EnterWriteLock ();
+                       this [line].IsFolded = !this [line].IsFolded;
+                       editMutex.ExitWriteLock ();
+                       FoldingEvent.Raise (this, new CodeBufferEventArgs (line));
+               }
+               public void Load(string rawSource, string lineBrkRegex = @"\r\n|\r|\n|\\\n") {
+                       this.Clear();
+
+                       if (string.IsNullOrEmpty (rawSource))
+                               return;
+
+                       AddRange (Regex.Split (rawSource, lineBrkRegex));
+
+                       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;
+                       editMutex.EnterReadLock ();
+                       for (int i = 0; i < this.LineCount; i++) {
+                               if (lines[i].PrintableLength > longestLineCharCount) {
+                                       longestLineCharCount = lines[i].PrintableLength;
+                                       longestLineIdx = i;
+                               }
+                       }
+                       editMutex.ExitReadLock ();
+                       //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 = "";
+                               editMutex.EnterReadLock ();
+                               for (int i = 0; i < lines.Count -1; i++)
+                                       tmp += lines [i].Content + this.lineBreak;
+                               tmp += lines [lines.Count - 1].Content;
+                               editMutex.ExitReadLock ();
+                               return tmp;
+                       }
+               }
+
+               /// <summary>
+               /// unfolded and not in folds line count
+               /// </summary>
+               public int UnfoldedLines {
+                       get {
+                               int i = 0, vl = 0;
+                               editMutex.EnterReadLock ();
+                               while (i < LineCount) {
+                                       if (this [i].IsFolded) {
+                                               i = GetEndNodeIndex (i);
+                                               if (i < 0) {
+                                                       Console.WriteLine ("error folding");
+                                                       break;
+                                               }
+                                       }
+                                       i++;
+                                       vl++;
+                               }
+                               editMutex.ExitReadLock ();
+                               //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);
+               }
+
+               int ConverteTabulatedPosOfCurLine (int column) {
+                       int tmp = 0;
+                       int i = 0;
+                       while (i < lines [_currentLine].Content.Length){
+                               if (lines [_currentLine].Content [i] == '\t')
+                                       tmp += 4;
+                               else
+                                       tmp++;
+                               if (tmp > column)
+                                       break;
+                               i++;
+                       }
+                       return i;
+               }
+
+               public int CurrentTabulatedColumn {
+                       get {
+                               return lines [_currentLine].Content.Substring (0, _currentCol).
+                                       Replace ("\t", new String (' ', Interface.TabSize)).Length;
+                       }
+               }
+               /// <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);
+               }
+               public void SetSelectionOnFullLines () {
+                       if (!SelectionInProgress)
+                               return;
+                       Point s = new Point (0, SelectionStart.Y);
+                       Point e = new Point (this [SelectionEnd.Y].Length, SelectionEnd.Y);
+                       selStartPos = s;
+                       selEndPos = e;
+                       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; } }
+               int requestedColumn = -1;
+               /// <summary>
+               /// Current column in buffer coordinate, tabulation = 1 char
+               /// </summary>
+               public int CurrentColumn{
+                       get { return _currentCol; }
+                       set {
+                               if (value == _currentCol)
+                                       return;
+
+                               editMutex.EnterReadLock ();
+
+                               if (value < 0)
+                                       _currentCol = 0;
+                               else if (value > lines [_currentLine].Length)
+                                       _currentCol = lines [_currentLine].Length;
+                               else
+                                       _currentCol = value;
+
+                               requestedColumn = CurrentTabulatedColumn;
+
+                               editMutex.ExitReadLock ();
+
+                               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;
+
+                               editMutex.EnterReadLock ();
+
+                               if (value >= lines.Count)
+                                       _currentLine = lines.Count-1;
+                               else if (value < 0)
+                                       _currentLine = 0;
+                               else
+                                       _currentLine = value;
+//                             if (_currentCol < 0)
+//                                     requestedColumn = tabu _currentCol;
+                               int tabulatedRequestedCol = ConverteTabulatedPosOfCurLine(requestedColumn);
+                               if (requestedColumn > lines [_currentLine].PrintableLength)
+                                       _currentCol = lines [_currentLine].Length;
+                               else
+                                       //_currentCol = requestedColumn;
+                                       _currentCol = tabulatedRequestedCol;
+                               //Debug.WriteLine ("buff cur line: " + _currentLine);
+
+                               editMutex.ExitReadLock();
+
+                               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()
+               {
+                       editMutex.EnterWriteLock ();
+                       if (SelectionIsEmpty) {
+                               if (CurrentColumn == 0) {
+                                       if (CurrentLine == 0) {
+                                               editMutex.ExitWriteLock ();
+                                               return;
+                                       }
+                                       CurrentLine--;
+                                       CurrentColumn = this [CurrentLine].Length;
+                                       AppenedLine (CurrentLine, this [CurrentLine + 1].Content);
+                                       RemoveAt (CurrentLine + 1);
+                                       editMutex.ExitWriteLock ();
+                                       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 ();
+                       }
+                       editMutex.ExitWriteLock ();
+               }
+               /// <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/Editors/CodeBuffer/CodeBufferEventArgs.cs b/CrowIDE/src/Editors/CodeBuffer/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/Editors/CodeBuffer/CodeLine.cs b/CrowIDE/src/Editors/CodeBuffer/CodeLine.cs
new file mode 100644 (file)
index 0000000..23f43fb
--- /dev/null
@@ -0,0 +1,82 @@
+using System;
+using System.Text;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Crow.Coding
+{
+       public class CodeLine
+       {
+               public string Content;
+               public List<Token> Tokens;
+               public int EndingState = 0;
+               public Node SyntacticNode;
+               public ParserException 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 ? false :
+                               SyntacticNode.EndLine != SyntacticNode.StartLine && SyntacticNode.EndLine != null; } }
+               public int FoldingLevel { get { return IsFoldable ? SyntacticNode.Level : 0; } }
+               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 int FirstNonBlankTokIndex {
+                       get { return Tokens == null ? -1 : Tokens.FindIndex (tk=>tk.Type != BufferParser.TokenType.WhiteSpace); }
+               }
+
+               public void SetLineInError (ParserException 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/Editors/CodeBuffer/Node.cs b/CrowIDE/src/Editors/CodeBuffer/Node.cs
new file mode 100644 (file)
index 0000000..9db5542
--- /dev/null
@@ -0,0 +1,36 @@
+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 int Level {
+                       get { return Parent == null ? 1 : Parent.Level + 1; } 
+               }
+
+               public override string ToString ()
+               {
+                       return string.Format ("Name:{0}, Type:{1}\n\tparent:{2}", Name, Type, Parent);
+               }
+       }
+}
+
diff --git a/CrowIDE/src/Editors/CodeBuffer/SourceEditor.cs b/CrowIDE/src/Editors/CodeBuffer/SourceEditor.cs
new file mode 100644 (file)
index 0000000..e605dd5
--- /dev/null
@@ -0,0 +1,1205 @@
+//
+// 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 : Editor
+       {               
+               #region CTOR
+               public SourceEditor (): base()
+               {
+                       formatting.Add ((int)XMLParser.TokenType.AttributeName, new TextFormatting (Color.Teal, 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.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.TractorRed, Color.Transparent, false, true));
+                       formatting.Add ((int)XMLParser.TokenType.XMLDecl, new TextFormatting (Color.AoEnglish, Color.Transparent));
+
+                       formatting.Add ((int)BufferParser.TokenType.BlockComment, new TextFormatting (Color.Gray, Color.Transparent, false, true));
+                       formatting.Add ((int)BufferParser.TokenType.LineComment, new TextFormatting (Color.Gray, Color.Transparent, false, true));
+                       formatting.Add ((int)BufferParser.TokenType.OperatorOrPunctuation, new TextFormatting (Color.Black, Color.Transparent));
+                       //formatting.Add ((int)BufferParser.TokenType.Keyword, new TextFormatting (Color.DarkCyan, Color.Transparent));
+
+                       parsing.Add (".crow", "Crow.Coding.XMLParser");
+                       parsing.Add (".svg", "Crow.Coding.XMLParser");
+                       parsing.Add (".template", "Crow.Coding.XMLParser");
+                       parsing.Add (".cs", "Crow.Coding.CSharpParser");
+                       parsing.Add (".style", "Crow.Coding.StyleParser");
+
+                       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(""));
+               }
+               #endregion
+
+               string oldSource = "";
+               //save requested position on error, and try it on next move
+               int requestedLine = 0, requestedCol = 0;
+               volatile bool isDirty = false;
+
+               const int leftMarginGap = 3;//gap between items in margin and text
+               const int foldSize = 9;//folding rectangles size
+               const int foldHSpace = 4;//folding level tabulation x
+               int foldMargin { get { return parser == null ? 0 : parser.SyntacticTreeMaxDepth * foldHSpace; }}//folding margin size
+
+               #region private and protected fields
+               bool foldingEnabled = true;
+               int leftMargin = 0;     //margin used to display line numbers, folding errors,etc...
+               int visibleLines = 1;
+               int visibleColumns = 1;
+               int firstPrintedLine = -1;
+               int printedCurrentLine = 0;//Index of the currentline in the PrintedLines array
+
+               CodeBuffer buffer;
+               BufferParser parser;
+               List<CodeLine> PrintedLines;//list of lines visible in the Editor depending on scrolling and folding
+
+               Dictionary<int, TextFormatting> formatting = new Dictionary<int, TextFormatting>();
+               Dictionary<string, string> parsing = new Dictionary<string, string>();
+
+               Color selBackground;
+               Color selForeground;
+               int selStartCol;
+               int selEndCol;
+
+               protected Rectangle rText;
+               protected FontExtents fe;
+               protected TextExtents te;
+
+               Point mouseLocalPos;
+               bool doubleClicked = false;
+               #endregion
+
+               void measureLeftMargin () {
+                       leftMargin = 0;
+                       if (PrintLineNumbers)
+                               leftMargin += (int)Math.Ceiling((double)buffer.LineCount.ToString().Length * fe.MaxXAdvance) +6;
+                       if (foldingEnabled)
+                               leftMargin += foldMargin;
+                       if (leftMargin > 0)
+                               leftMargin += leftMarginGap;                    
+                       updateVisibleColumns ();
+               }
+               void findLongestLineAndUpdateMaxScrollX() {
+                       buffer.FindLongestVisualLine ();
+                       updateMaxScrollX ();
+//                     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.Ascent+fe.Descent));
+                       NotifyValueChanged ("VisibleLines", visibleLines);
+                       updateMaxScrollY ();
+                       updatePrintedLines ();
+                       RegisterForGraphicUpdate ();
+//                     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);
+                       NotifyValueChanged ("VisibleColumns", visibleColumns);
+                       updateMaxScrollX ();
+//                     System.Diagnostics.Debug.WriteLine ("update visible columns: {0} leftMargin:{1}",visibleColumns, leftMargin);
+//                     System.Diagnostics.Debug.WriteLine ("update MaxScrollX: " + MaxScrollX);
+               }
+               void updateMaxScrollX () {
+                       MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns);
+                       if (buffer.longestLineCharCount > 0)
+                               NotifyValueChanged ("ChildWidthRatio", Slot.Width * visibleColumns / buffer.longestLineCharCount);                      
+               }
+               void updateMaxScrollY () {
+                       if (parser == null || !foldingEnabled) {
+                               MaxScrollY = Math.Max (0, buffer.LineCount - visibleLines);
+                               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);                                                     
+                       }
+               }                       
+               void updatePrintedLines () {
+                       buffer.editMutex.EnterReadLock ();
+                       editorMutex.EnterWriteLock ();
+
+                       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++;
+                       }
+
+                       buffer.editMutex.ExitReadLock ();
+                       editorMutex.ExitWriteLock ();
+               }
+               void updateOnScreenCurLineFromBuffCurLine(){
+                       printedCurrentLine = PrintedLines.IndexOf (buffer.CurrentCodeLine);
+               }
+               void toogleFolding (int line) {
+                       if (parser == null || !foldingEnabled)
+                               return;
+                       buffer.ToogleFolding (line);
+               }
+
+               #region Editor overrides
+               protected override void updateEditorFromProjFile ()
+               {
+                       buffer.editMutex.EnterWriteLock ();
+                       loadSource ();
+                       buffer.editMutex.ExitWriteLock ();
+
+                       isDirty = false;
+                       oldSource = projFile.Source;
+                       CurrentLine = requestedLine;
+                       CurrentColumn = requestedCol;
+                       projFile.RegisteredEditors [this] = true;
+               }
+               protected override void updateProjFileFromEditor ()
+               {
+                       buffer.editMutex.EnterWriteLock ();
+                       string newsrc = buffer.FullText;
+                       buffer.editMutex.ExitWriteLock ();
+                       projFile.UpdateSource (this, newsrc);
+               }
+               protected override bool EditorIsDirty {
+                       get { return isDirty; }
+                       set { isDirty = value; }
+               }
+               protected override bool IsReady {
+                       get { return buffer != null; }
+               }
+               #endregion
+
+               #region Buffer events handlers
+               void Buffer_BufferCleared (object sender, EventArgs e)
+               {
+                       editorMutex.EnterWriteLock ();
+
+                       buffer.longestLineCharCount = 0;
+                       buffer.longestLineIdx = 0;
+                       measureLeftMargin ();
+                       MaxScrollX = MaxScrollY = 0;
+                       PrintedLines = null;
+                       RegisterForGraphicUpdate ();
+                       notifyPositionChanged ();
+                       isDirty = true;
+
+                       editorMutex.ExitWriteLock ();
+               }
+               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);
+                       }
+
+                       if (parser != null)
+                               parser.reparseSource ();
+
+                       measureLeftMargin ();
+
+                       updatePrintedLines ();
+                       updateMaxScrollY ();
+                       RegisterForGraphicUpdate ();
+                       notifyPositionChanged ();
+                       isDirty = true;
+               }
+               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 ();
+                       notifyPositionChanged ();
+                       isDirty = true;
+               }
+               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 ();
+                       notifyPositionChanged ();
+                       isDirty = true;
+               }
+               void Buffer_PositionChanged (object sender, EventArgs e)
+               {
+                       Console.WriteLine ("Position changes: ({0},{1})", buffer.CurrentLine, buffer.CurrentColumn);
+                       int cc = buffer.CurrentTabulatedColumn;
+
+                       if (cc > visibleColumns + ScrollX) {
+                               ScrollX = cc - visibleColumns;
+                       } else if (cc < ScrollX)
+                               ScrollX = cc;
+                       
+                       RegisterForGraphicUpdate ();
+                       updateOnScreenCurLineFromBuffCurLine ();
+                       notifyPositionChanged ();
+               }
+
+               void Buffer_SelectionChanged (object sender, EventArgs e)
+               {
+                       RegisterForGraphicUpdate ();
+               }
+               void Buffer_FoldingEvent (object sender, CodeBufferEventArgs e)
+               {
+                       updatePrintedLines ();
+                       updateOnScreenCurLineFromBuffCurLine ();
+                       updateMaxScrollY ();
+                       RegisterForGraphicUpdate ();
+               }
+               #endregion
+
+               void notifyPositionChanged (){
+                       try {                           
+                               NotifyValueChanged ("CurrentLine", buffer.CurrentLine+1);
+                               NotifyValueChanged ("CurrentColumn", buffer.CurrentColumn+1);
+                               NotifyValueChanged ("CurrentLineHasError", CurrentLineHasError);
+                               NotifyValueChanged ("CurrentLineError", CurrentLineError);
+                       } catch (Exception ex) {
+                               Console.WriteLine (ex.ToString ());
+                       }
+               }
+                       
+               #region Public Crow Properties
+               public int CurrentLine{
+                       get { return buffer == null ? 0 : buffer.CurrentLine+1; }
+                       set {
+                               try {
+                                       int l = value - 1;
+                                       if (l == buffer.CurrentLine)
+                                               return;
+                                       buffer.CurrentLine = l;
+                                       if (buffer [l].IsFolded)
+                                               buffer.ToogleFolding (l);                                       
+                               } catch (Exception ex) {
+                                       requestedLine = value - 1;
+                                       Console.WriteLine ("Error cur column: " + ex.ToString ());
+                               }
+                       }
+               }
+               public int CurrentColumn{
+                       get { return buffer == null ? 0 : buffer.CurrentColumn+1; }
+                       set {
+                               try {                                   
+                                       if (value - 1 == buffer.CurrentColumn)
+                                               return;
+                                       buffer.CurrentColumn = value - 1;
+                               } catch (Exception ex) {
+                                       requestedCol = value - 1;
+                                       Console.WriteLine ("Error cur column: " + ex.ToString ());
+                               }
+                       }
+               }
+               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 ();
+                       }
+               }
+               [DefaultValue("BlueGray")]
+               public virtual Color SelectionBackground {
+                       get { return selBackground; }
+                       set {
+                               if (value == selBackground)
+                                       return;
+                               selBackground = value;
+                               NotifyValueChanged ("SelectionBackground", selBackground);
+                               RegisterForRedraw ();
+                       }
+               }
+               [DefaultValue("White")]
+               public virtual Color SelectionForeground {
+                       get { return selForeground; }
+                       set {
+                               if (value == selForeground)
+                                       return;
+                               selForeground = value;
+                               NotifyValueChanged ("SelectionForeground", selForeground);
+                               RegisterForRedraw ();
+                       }
+               }
+               public override int ScrollY {
+                       get {
+                               return base.ScrollY;
+                       }
+                       set {
+                               if (value == base.ScrollY)
+                                       return;
+                               base.ScrollY = value;
+                               updatePrintedLines ();
+                               updateOnScreenCurLineFromBuffCurLine ();
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+               public ParserException CurrentLineError {
+                       get { return buffer?.CurrentCodeLine?.exception; }
+               }
+               public bool CurrentLineHasError {
+                       get { return buffer == null ? false : buffer.CurrentCodeLine == null ? false :
+                               buffer.CurrentCodeLine.exception != null; }
+               }
+               public override ProjectFile ProjectNode {
+                       get {
+                               return base.ProjectNode;
+                       }
+                       set {
+                               base.ProjectNode = value;
+                               if (projFile != null)
+                                       parser = getParserFromExt (System.IO.Path.GetExtension (projFile.Extension));
+                       }
+               }
+               #endregion
+
+               BufferParser 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 (BufferParser)Activator.CreateInstance (parserType, buffer );
+               }
+               void loadSource () {
+
+                       try {
+
+                               if (parser == null)
+                                       buffer.Load (projFile.Source);
+                               else//parser may have special linebrk rules
+                                       buffer.Load (projFile.Source, parser.LineBrkRegex);
+
+                       } catch (Exception ex) {
+                               Debug.WriteLine (ex.ToString ());
+                       }
+
+                       projFile.RegisteredEditors [this] = true;
+
+                       updateMaxScrollY ();
+                       MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns);
+                       updatePrintedLines ();
+
+                       RegisterForGraphicUpdate ();
+               }
+
+               /// <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.Ascent+fe.Descent) * 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.Ascent+fe.Descent)));
+                               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;
+                                       mgBg = Color.DarkGray;
+                               }
+                               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){
+
+                               Rectangle rFld = new Rectangle (cb.X + leftMargin - leftMarginGap - foldMargin,
+                                       (int)(y + (fe.Ascent + fe.Descent) / 2.0 - foldSize / 2.0), foldSize, foldSize);
+
+                               gr.SetSourceColor (Color.Black);
+                               gr.LineWidth = 1.0;
+
+                               int level = 0;
+                               bool closingNode = false;
+
+                               if (currentNode != null) {
+                                       if (cl == currentNode.EndLine) {
+                                               currentNode = currentNode.Parent;
+                                               closingNode = true;
+                                       }
+                                       if (currentNode != null)
+                                               level = currentNode.Level - 1;
+                               }
+
+                               for (int l = 0; l < level; l++) {                                       
+                                       gr.MoveTo (rFld.Center.X + 0.5, y);
+                                       gr.LineTo (rFld.Center.X + 0.5, y + fe.Ascent + fe.Descent);
+                                       rFld.Left += foldHSpace;
+                               }
+                               if (closingNode) {
+                                       gr.MoveTo (rFld.Center.X + 0.5, y);
+                                       gr.LineTo (rFld.Center.X + 0.5, y + fe.Ascent / 2 + 0.5);
+                                       gr.LineTo (rFld.Center.X + 0.5 + foldSize / 2, y + fe.Ascent / 2 + 0.5);
+                                       closingNode = false;
+                               }
+                               gr.SetDash (new double[]{ 1.5 },0.0);
+                               gr.SetSourceColor (Color.Gray);
+                               gr.Stroke ();
+                               gr.SetDash (new double[]{}, 0.0);
+
+                               if (cl.IsFoldable) {
+                                       gr.Rectangle (rFld);
+                                       gr.SetSourceColor (Color.White);
+                                       gr.Fill();
+                                       gr.SetSourceColor (Color.Black);
+                                       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);
+                                       }else
+                                               currentNode = cl.SyntacticNode;
+                                       
+                                       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);
+               }
+               Node currentNode = null;
+//             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.Ascent+fe.Descent));
+//                             gr.LineTo (0.5 + cursorX, cb.Y + (printedCurrentLine + 1) * (fe.Ascent+fe.Descent));
+//                             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.Ascent+fe.Descent));
+                               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.Ascent+fe.Descent));
+                                       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.Ascent+fe.Descent) * 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 ();
+               }
+
+               protected override void onDraw (Context gr)
+               {
+                       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);
+
+                       buffer.editMutex.EnterReadLock ();
+                       editorMutex.EnterReadLock ();
+
+                       #region draw text cursor
+                       if (buffer.SelectionInProgress){
+                               selStartCol = getTabulatedColumn (buffer.SelectionStart);
+                               selEndCol = getTabulatedColumn (buffer.SelectionEnd);
+                       }else if (HasFocus && printedCurrentLine >= 0){
+                               gr.LineWidth = 1.0;
+                               double cursorX = cb.X + (getTabulatedColumn(buffer.CurrentPosition) - ScrollX) * fe.MaxXAdvance + leftMargin;
+                               gr.MoveTo (0.5 + cursorX, cb.Y + (printedCurrentLine) * (fe.Ascent+fe.Descent));
+                               gr.LineTo (0.5 + cursorX, cb.Y + (printedCurrentLine + 1) * (fe.Ascent+fe.Descent));
+                               gr.Stroke();
+                       }
+                       #endregion
+
+                       if (PrintedLines?.Count > 0) {                          
+                               int unfoldedLines = buffer.UnfoldedLines;
+                               currentNode = null;
+                               CodeLine cl = PrintedLines[0];
+                               int idx0 = buffer.IndexOf(cl);
+                               int li = idx0-1;
+                               while (li >= 0) {
+                                       if (buffer [li].IsFoldable && !buffer [li].IsFolded) {
+                                               if (buffer.IndexOf(buffer [li].SyntacticNode.EndLine) > idx0){
+                                                       currentNode = buffer [li].SyntacticNode;
+                                                       break;
+                                               }
+                                       }
+                                       li--;
+                               }
+
+                               for (int i = 0; i < visibleLines; i++) {
+                                       if (i + ScrollY >= unfoldedLines)//TODO:need optimize
+                                               break;
+                                       drawLine (gr, cb, i);
+                               }
+                       }
+
+                       editorMutex.ExitReadLock ();
+
+                       buffer.editMutex.ExitReadLock ();
+
+               }
+               #endregion
+
+               #region Mouse handling
+
+               int hoverLine = -1;
+               public int HoverLine {
+                       get { return hoverLine; }
+                       set { 
+                               if (hoverLine == value)
+                                       return;
+                               hoverLine = value;
+                               NotifyValueChanged ("HoverLine", hoverLine);                            
+                       }
+               }
+               void updateHoverLine () {
+                       int hvl = (int)Math.Max (0, Math.Floor (mouseLocalPos.Y / (fe.Ascent+fe.Descent)));
+                       hvl = Math.Min (PrintedLines.Count, hvl);
+                       HoverLine = buffer.IndexOf (PrintedLines[hvl]);
+               }
+               void updateCurrentPosFromMouseLocalPos(){                       
+                       PrintedCurrentLine = (int)Math.Max (0, Math.Floor (mouseLocalPos.Y / (fe.Ascent+fe.Descent)));
+                       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;
+               }
+               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;
+
+                       updateHoverLine ();
+
+                       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
+                       updateCurrentPosFromMouseLocalPos();
+                       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.Ascent+fe.Descent)))]));
+                               return;
+                       }
+
+                       updateCurrentPosFromMouseLocalPos ();
+                       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;
+
+                       if (e.Control) {
+                               switch (key) {
+                               case Key.S:
+                                       projFile.Save ();
+                                       break;
+                               case Key.W:
+                                       editorMutex.EnterWriteLock ();
+                                       if (e.Shift)
+                                               projFile.Redo (null);
+                                       else
+                                               projFile.Undo (null);
+                                       editorMutex.ExitWriteLock ();
+                                       break;
+                               default:
+                                       Console.WriteLine ("");
+                                       break;
+                               }
+                       }
+
+                       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:
+                               if (e.Shift) {
+                                       if (buffer.SelectionIsEmpty ||
+                                               (buffer.SelectionStart.Y == buffer.SelectionEnd.Y)) {
+                                               //TODO
+                                               break;
+                                       }
+                                       for (int i = buffer.SelectionStart.Y; i <= buffer.SelectionEnd.Y; i++)
+                                               buffer.RemoveLeadingTab (i);
+                                       buffer.SetSelectionOnFullLines ();
+                               } else {
+                                       if (buffer.SelectionIsEmpty ||
+                                               (buffer.SelectionStart.Y == buffer.SelectionEnd.Y)) {
+                                               buffer.Insert ("\t");
+                                               break;
+                                       }
+                                       for (int i = buffer.SelectionStart.Y; i <= buffer.SelectionEnd.Y; i++) {
+                                               buffer.UpdateLine (i, "\t" + buffer [i].Content);
+                                       }
+                               }
+
+                               break;
+                       case Key.F8:
+                               toogleFolding (buffer.CurrentLine);
+                               break;
+                       default:
+                               break;
+                       }
+                       RegisterForGraphicUpdate();
+               }
+               public override void onKeyPress (object sender, KeyPressEventArgs e)
+               {
+                       base.onKeyPress (sender, e);
+
+                       buffer.Insert (e.KeyChar.ToString());
+                       buffer.ResetSelection ();
+               }
+               #endregion
+       }
+}
\ No newline at end of file
diff --git a/CrowIDE/src/Editors/CodeBuffer/TextFormatting.cs b/CrowIDE/src/Editors/CodeBuffer/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/Editors/CodeBuffer/Token.cs b/CrowIDE/src/Editors/CodeBuffer/Token.cs
new file mode 100644 (file)
index 0000000..8b4df5e
--- /dev/null
@@ -0,0 +1,71 @@
+//
+//  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 BufferParser.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 IsNull { get { return IsEmpty && Type == BufferParser.TokenType.Unknown; }}
+               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/Editors/EditPane.cs b/CrowIDE/src/Editors/EditPane.cs
new file mode 100644 (file)
index 0000000..a75522f
--- /dev/null
@@ -0,0 +1,57 @@
+//
+// EditPane.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 Crow;
+using System.Linq;
+
+namespace Crow.Coding
+{
+       public class EditPane : TemplatedGroup
+       {
+               public EditPane () {}
+
+               object selectedItemElement = null;
+
+               public override int SelectedIndex {
+                       get {
+                               return base.SelectedIndex;
+                       }
+                       set {
+                               base.SelectedIndex = value;
+                       }
+               }
+               public object SelectedItemElement {
+                       get { return selectedItemElement; }
+                       set {
+                               if (selectedItemElement == value)
+                                       return;
+                               selectedItemElement = value;
+                               NotifyValueChanged ("SelectedItemElement", selectedItemElement);
+                       }
+               }
+       }
+}
+
diff --git a/CrowIDE/src/Editors/Editor.cs b/CrowIDE/src/Editors/Editor.cs
new file mode 100644 (file)
index 0000000..88cab8e
--- /dev/null
@@ -0,0 +1,104 @@
+//
+// Editor.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.Threading;
+using System.Xml.Serialization;
+
+namespace Crow.Coding
+{
+       public abstract class Editor : ScrollingObject
+       {
+               #region CTOR
+               protected Editor ():base(){
+                       Thread t = new Thread (backgroundThreadFunc);
+                       t.IsBackground = true;
+                       t.Start ();
+               }
+               #endregion
+
+               protected ReaderWriterLockSlim editorMutex = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
+               protected ProjectFile projFile = null;
+               Exception error = null;
+
+               public virtual ProjectFile ProjectNode
+               {
+                       get { return projFile; }
+                       set
+                       {
+                               if (projFile == value)
+                                       return;
+
+                               if (projFile != null)
+                                       projFile.UnregisterEditor (this);
+
+                               projFile = value;
+
+                               if (projFile != null)                                   
+                                       projFile.RegisterEditor (this);
+
+                               NotifyValueChanged ("ProjectNode", projFile);
+                       }
+               }
+               [XmlIgnore]public Exception Error {
+                       get { return error; }
+                       set {
+                               if (error == value)
+                                       return;
+                               error = value;
+                               NotifyValueChanged ("Error", error);
+                               NotifyValueChanged ("HasError", HasError);
+                       }
+               }
+               [XmlIgnore]public bool HasError {
+                       get { return error != null; }
+               }
+
+               protected abstract void updateEditorFromProjFile ();
+               protected abstract void updateProjFileFromEditor ();
+               protected abstract bool EditorIsDirty { get; set; }
+               protected virtual bool IsReady { get { return true; }}
+               protected virtual void updateCheckPostProcess () {}
+
+               protected void backgroundThreadFunc () {
+                       while (true) {
+                               if (IsReady) {
+                                       if (projFile != null) {
+                                               if (!projFile.RegisteredEditors [this]) {
+                                                       projFile.RegisteredEditors [this] = true;
+                                                       updateEditorFromProjFile ();
+                                               } else if (EditorIsDirty) {
+                                                       EditorIsDirty = false;
+                                                       updateProjFileFromEditor ();
+                                               }
+                                               updateCheckPostProcess ();
+                                       }
+                               }
+                               Thread.Sleep (10);
+                       }       
+               }
+       }
+}
+
diff --git a/CrowIDE/src/Editors/ImlVisualEditor.cs b/CrowIDE/src/Editors/ImlVisualEditor.cs
new file mode 100644 (file)
index 0000000..1ba6c55
--- /dev/null
@@ -0,0 +1,520 @@
+//
+//  ImlVisualEditor.cs
+//
+//  Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+//  Copyright (c) 2016 jp
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+using System;
+using Crow;
+using System.Threading;
+using System.Xml.Serialization;
+using System.ComponentModel;
+using System.IO;
+using System.Collections.Generic;
+using Crow.IML;
+using System.Text;
+using System.Xml;
+
+namespace Crow.Coding
+{
+       public class ImlVisualEditor : Editor
+       {
+               #region CTOR
+               public ImlVisualEditor () : base()
+               {
+                       imlVE = new DesignInterface ();
+               }
+               #endregion
+
+               DesignInterface imlVE;
+               GraphicObject selectedItem;
+               ImlProjectItem imlProjFile;
+               Exception imlError = null;
+
+               bool drawGrid, snapToGrid;
+               int gridSpacing;
+
+               [DefaultValue(true)]
+               public bool DrawGrid {
+                       get { return drawGrid; }
+                       set {
+                               if (drawGrid == value)
+                                       return;
+                               drawGrid = value;
+                               NotifyValueChanged ("DrawGrid", drawGrid);
+                               RegisterForRedraw ();
+                       }
+               }
+               [DefaultValue(true)]
+               public bool SnapToGrid {
+                       get { return snapToGrid; }
+                       set {
+                               if (snapToGrid == value)
+                                       return;
+                               snapToGrid = value;
+                               NotifyValueChanged ("SnapToGrid", snapToGrid);
+                       }
+               }
+               [DefaultValue(10)]
+               public int GridSpacing {
+                       get { return gridSpacing; }
+                       set {
+                               if (gridSpacing == value)
+                                       return;
+                               gridSpacing = value;
+                               NotifyValueChanged ("GridSpacing", gridSpacing);
+                               RegisterForRedraw ();
+                       }
+               }
+               [XmlAttributeAttribute]public GraphicObject SelectedItem {
+                       get { return selectedItem; }
+                       set {
+                               if (selectedItem == value)
+                                       return;
+                               selectedItem = value;
+                               NotifyValueChanged ("SelectedItem", selectedItem);
+                               RegisterForRedraw ();
+                       }
+               }
+               /// <summary>PoinprojFilever the widget</summary>
+               public virtual GraphicObject HoverWidget
+               {
+                       get { return imlVE.HoverWidget; }
+                       set {
+                               if (HoverWidget == value)
+                                       return;
+                               
+                               imlVE.HoverWidget = value;
+
+                               NotifyValueChanged ("HoverWidget", HoverWidget);
+                       }
+               }
+               [XmlIgnore]public List<LQIList> LQIs {
+                       get { return imlVE.LQIs; }
+               }
+
+               public override ProjectFile ProjectNode {
+                       get {
+                               return base.ProjectNode;
+                       }
+                       set {
+                               base.ProjectNode = value;
+                               imlProjFile = projFile as ImlProjectItem;
+                               imlVE.ProjFile = imlProjFile;
+                       }
+               }
+
+               public List<GraphicObject> GraphicTree {
+                       get { return imlVE.GraphicTree; }
+               }
+               protected override void updateProjFileFromEditor ()
+               {
+                       try {
+                               projFile.UpdateSource(this, imlProjFile.Instance.GetIML());
+                       } catch (Exception ex) {
+                               Error = ex.InnerException;
+                               if (Monitor.IsEntered(imlVE.UpdateMutex))
+                                       Monitor.Exit (imlVE.UpdateMutex);
+                       }
+               }
+               protected override void updateEditorFromProjFile () {
+                       try {
+                               string selItemDesignID = null;
+                               if (SelectedItem!=null)
+                                       selItemDesignID = SelectedItem.design_id;
+                               imlVE.ClearInterface();
+                               Instantiator.NextInstantiatorID = 0;
+                               imlVE.Styling = projFile.Project.solution.Styling;
+                               imlVE.DefaultValuesLoader.Clear();
+                               imlVE.DefaultTemplates = projFile.Project.solution.DefaultTemplates;
+                               imlVE.Instantiators = new Dictionary<string, Instantiator>();
+
+                               //prevent error on empty file
+                               bool emptyFile = true;
+                               string src = projFile.Source;
+                               using (Stream s = new MemoryStream (Encoding.UTF8.GetBytes (src))) {
+                                       using (XmlReader itr = XmlReader.Create (s)) {
+                                               while(itr.Read()){
+                                                       if (itr.NodeType == XmlNodeType.Element){
+                                                               emptyFile = false;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+                               GraphicObject go = null;
+                               Error = null;
+
+                               if (emptyFile){
+                                       imlProjFile.Instance = null;
+                               }else{
+                                       imlVE.LoadIMLFragment(src);
+                                       imlProjFile.Instance = imlVE.GraphicTree[0];
+                                       if (selItemDesignID!=null)
+                                               imlProjFile.Instance.FindByDesignID(selItemDesignID,out go);                                            
+
+                               }
+                               SelectedItem = go;
+                       } catch (Exception ex) {
+                               Error = ex.InnerException;
+                               if (Monitor.IsEntered(imlVE.UpdateMutex))
+                                       Monitor.Exit (imlVE.UpdateMutex);
+                       }
+               }
+
+               protected override bool EditorIsDirty {
+                       get { return imlProjFile == null ? false :
+                               imlProjFile.Instance == null ? false : imlProjFile.Instance.design_HasChanged; }
+                       set {
+                               if (GraphicTree [0] != null)
+                                       GraphicTree [0].design_HasChanged = value;                      
+                       }
+               }
+               protected override bool IsReady {
+                       get { return updateEnabled && imlVE != null && imlProjFile != null; }
+               }
+               bool updateEnabled;
+               /// <summary>
+               /// use to disable update if tab is not the visible one
+               /// </summary>
+               public bool UpdateEnabled {
+                       get { return updateEnabled; }
+                       set { 
+                               if (value == updateEnabled)
+                                       return;
+                               updateEnabled = value;
+                               NotifyValueChanged ("UpdateEnabled", updateEnabled);
+                       }
+               }
+               protected override void updateCheckPostProcess ()
+               {
+                       imlVE.Update ();
+                       bool isDirty = false;
+
+                       lock (imlVE.RenderMutex)
+                               isDirty = imlVE.IsDirty;
+
+                       if (isDirty) {
+                               lock (IFace.UpdateMutex)
+                                       RegisterForRedraw ();
+                       }
+               }
+
+               #region GraphicObject overrides
+               public override void OnLayoutChanges (LayoutingType layoutType)
+               {
+                       base.OnLayoutChanges (layoutType);
+                       switch (layoutType) {
+                       case LayoutingType.Width:
+                       case LayoutingType.Height:
+                               imlVE.ProcessResize (this.ClientRectangle.Size);
+                               break;
+                       }
+               }
+
+               public override void onMouseMove (object sender, MouseMoveEventArgs e)
+               {
+                       base.onMouseMove (sender, e);
+
+                       GraphicObject oldHW = HoverWidget;
+                       Rectangle scr = this.ScreenCoordinates (this.getSlot ());
+                       ProcessMouseMove (e.X - scr.X, e.Y - scr.Y);
+
+                       if (oldHW == HoverWidget)
+                               return;
+
+                       if (draggedObj != null) {
+                               if (isPossibleContainer (HoverWidget) && draggedObjContainer != HoverWidget) {
+                                       removeDraggedObjFrom ();
+                                       tryAddDraggedObjTo (HoverWidget);
+                               }
+                       }
+
+                       RegisterForRedraw ();
+
+               }
+               public override void onMouseDown (object sender, MouseButtonEventArgs e)
+               {
+                       //base.onMouseDown (sender, e);
+                       SelectedItem = HoverWidget;
+
+                       if (SelectedItem != null && projFile != null) {
+                               projFile.CurrentLine = SelectedItem.design_line;
+                               projFile.CurrentColumn = SelectedItem.design_column;
+                       }
+
+               }
+
+               protected override void onDraw (Cairo.Context gr)
+               {
+                       base.onDraw (gr);
+                       if (!drawGrid)
+                               return;
+
+
+                       Rectangle cb = ClientRectangle;
+                       const double gridLineWidth = 0.1;
+                       double glhw = gridLineWidth / 2.0;
+                       int nbLines = cb.Width / gridSpacing ;
+                       double d = cb.Left + gridSpacing;
+                       for (int i = 0; i < nbLines; i++) {
+                               gr.MoveTo (d-glhw, cb.Y);
+                               gr.LineTo (d-glhw, cb.Bottom);
+                               d += gridSpacing;
+                       }
+                       nbLines = cb.Height / gridSpacing;
+                       d = cb.Top + gridSpacing;
+                       for (int i = 0; i < nbLines; i++) {
+                               gr.MoveTo (cb.X, d - glhw);
+                               gr.LineTo (cb.Right, d -glhw);
+                               d += gridSpacing;
+                       }
+                       gr.LineWidth = gridLineWidth;
+                       Foreground.SetAsSource (gr, cb);
+                       gr.Stroke ();
+
+                       lock (imlVE.RenderMutex) {
+                               using (Cairo.Surface surf = new Cairo.ImageSurface (imlVE.bmp, Cairo.Format.Argb32,
+                                       imlVE.ClientRectangle.Width, imlVE.ClientRectangle.Height, imlVE.ClientRectangle.Width * 4)) {
+                                       gr.SetSourceSurface (surf, cb.Left, cb.Top);
+                                       gr.Paint ();
+                               }
+                               imlVE.IsDirty = false;
+                       }
+
+                       Rectangle hr;
+                       if (HoverWidget != null) {
+                               hr = HoverWidget.ScreenCoordinates (HoverWidget.getSlot ());
+//                     gr.SetSourceColor (Color.LightGray);
+//                     gr.DrawCote (new Cairo.PointD (hr.X, hr.Center.Y), new Cairo.PointD (hr.Right, hr.Center.Y));
+//                     gr.DrawCote (new Cairo.PointD (hr.Center.X, hr.Y), new Cairo.PointD (hr.Center.X, hr.Bottom));
+                               //hr.Inflate (2);
+                               gr.SetSourceColor (Color.LightGray);
+                               gr.SetDash (new double[]{ 3.0, 3.0 }, 0.0);
+                               gr.Rectangle (hr, 1.0);
+                       }
+
+                       if (SelectedItem?.Parent == null)
+                               return;
+                       hr = SelectedItem.ScreenCoordinates(SelectedItem.getSlot ());
+                       hr.Inflate (1);
+                       gr.LineWidth = 2;
+                       gr.SetSourceColor (Color.Yellow);
+                       gr.SetDash (new double[]{ 5.0, 3.0 },0.0);
+                       gr.Rectangle (hr, 1.0);
+               }
+
+               protected override void onDragEnter (object sender, DragDropEventArgs e)
+               {
+                       base.onDragEnter (sender, e);
+                       GraphicObjectDesignContainer godc = e.DragSource.DataSource as GraphicObjectDesignContainer;
+                       if (godc == null)
+                               return;
+                       createDraggedObj (godc.CrowType);
+               }
+               protected override void onDragLeave (object sender, DragDropEventArgs e)
+               {
+                       base.onDragLeave (sender, e);
+
+                       ClearDraggedObj ();
+               }
+               #endregion
+
+               #region draggedObj handling
+               public GraphicObject draggedObj = null;
+               public GraphicObject draggedObjContainer = null;
+
+               bool tryAddDraggedObjTo(GraphicObject g){
+                       lock (imlVE.UpdateMutex) {
+                               if (g.GetType ().IsSubclassOf (typeof(Container))) {
+                                       Container c = g as Container;
+                                       c.SetChild (draggedObj);
+                                       EditorIsDirty = true;
+                               } else if (g.GetType ().IsSubclassOf (typeof(Group))) {
+                                       Group c = g as Group;
+                                       c.AddChild (draggedObj);
+                               } else
+                                       return false;
+                               EditorIsDirty = true;
+                               draggedObjContainer = g;
+                       }
+                       return true;
+               }
+               bool isPossibleContainer (GraphicObject g){
+                       if (g.GetType().IsSubclassOf(typeof(Container))){
+                               Container c = g as Container;
+                               return c.Child == null;
+                       }
+                       return g.GetType ().IsSubclassOf (typeof(Group));
+               }
+               void removeDraggedObjFrom(){
+                       if (draggedObjContainer == null)
+                               return;
+                       lock (imlVE.UpdateMutex) {
+                               if (draggedObjContainer.GetType().IsSubclassOf(typeof(Container))){
+                                       Container c = draggedObjContainer as Container;
+                                       c.SetChild (null);
+                                       EditorIsDirty = true;
+                                       //Console.WriteLine ("remove {0} from {1}", draggedObj, c);
+                               }else if (draggedObjContainer.GetType().IsSubclassOf(typeof(Group))){
+                                       Group c = draggedObjContainer as Group;
+                                       c.RemoveChild (draggedObj);
+                                       EditorIsDirty = true;
+                                       //Console.WriteLine ("remove {0} from {1}", draggedObj, c);
+                               }//else
+                               //      Console.WriteLine ("Error removing dragged obj");
+                       }
+                       draggedObjContainer = null;
+               }
+               void createDraggedObj (Type crowType) {
+                       lock (imlVE.UpdateMutex) {
+                               draggedObj = imlVE.CreateITorFromIMLFragment ("<" + crowType.Name + "/>").CreateInstance ();
+                       }
+               }
+               public void ClearDraggedObj (bool removeFromTree = true) {
+                       //Console.WriteLine ("Clear dragged obj {0}, remove from tree = {1}", draggedObj, removeFromTree);
+                       if (removeFromTree)
+                               removeDraggedObjFrom ();
+                       draggedObjContainer = null;
+                       if (draggedObj == null)
+                               return;
+                       if (removeFromTree)
+                               draggedObj.Dispose ();
+                       draggedObj = null;
+               }
+               #endregion
+
+
+               void WidgetCheckOver (GraphicObject go, MouseMoveEventArgs e){
+                       Type tGo = go.GetType();
+                       if (typeof(TemplatedGroup).IsAssignableFrom (tGo)) {
+                               
+                       } else if (typeof(TemplatedContainer).IsAssignableFrom (tGo)) {
+                               TemplatedContainer c = go as TemplatedContainer;
+                               if (c.Content?.MouseIsIn (e.Position) == true) {                                        
+                                       WidgetCheckOver (c.Content, e);
+                                       return;
+                               }
+                       } else if (typeof(TemplatedControl).IsAssignableFrom (tGo)) {
+                       } else if (typeof(Group).IsAssignableFrom (tGo)) {
+                               Group c = go as Group;
+                               for (int i = c.Children.Count -1; i >= 0; i--) {
+                                       if (c.Children[i].MouseIsIn (e.Position)) {                                     
+                                               WidgetCheckOver (c.Children[i], e);
+                                               return;
+                                       }
+                               }
+                       } else if (typeof(Crow.Container).IsAssignableFrom (tGo)) {
+                               Crow.Container c = go as Crow.Container;
+                               if (c.Child?.MouseIsIn (e.Position)==true) {                                    
+                                       WidgetCheckOver (c.Child, e);
+                                       return;
+                               }
+                       }
+                       HoverWidget = go;
+                       WidgetMouseEnter (go, e);
+               }
+               void WidgetMouseLeave (GraphicObject go, MouseMoveEventArgs e){
+
+               }
+               void WidgetMouseEnter (GraphicObject go, MouseMoveEventArgs e){
+
+               }
+               void WidgetMouseMove (GraphicObject go, MouseMoveEventArgs e){}
+               public bool ProcessMouseMove(int x, int y)
+               {
+                       int deltaX = x - imlVE.Mouse.X;
+                       int deltaY = y - imlVE.Mouse.Y;
+                       imlVE.Mouse.X = x;
+                       imlVE.Mouse.Y = y;
+                       MouseMoveEventArgs e = new MouseMoveEventArgs (x, y, deltaX, deltaY);
+                       e.Mouse = imlVE.Mouse;
+
+                       if (imlVE.ActiveWidget != null) {
+                               //TODO, ensure object is still in the graphic tree
+                               //send move evt even if mouse move outside bounds
+                               WidgetMouseMove (imlVE.ActiveWidget, e);
+                               return true;
+                       }
+
+                       if (HoverWidget != null) {
+                               //TODO, ensure object is still in the graphic tree
+                               //check topmost graphicobject first
+                               GraphicObject tmp = HoverWidget;
+                               GraphicObject topc = null;
+                               while (tmp is GraphicObject) {
+                                       topc = tmp;
+                                       tmp = tmp.LogicalParent as GraphicObject;
+                               }
+                               int idxhw = imlVE.GraphicTree.IndexOf (topc);
+                               if (idxhw != 0) {
+                                       int i = 0;
+                                       while (i < idxhw) {
+                                               if (imlVE.GraphicTree [i].LogicalParent == imlVE.GraphicTree [i].Parent) {
+                                                       if (imlVE.GraphicTree [i].MouseIsIn (e.Position)) {
+                                                               while (imlVE.HoverWidget != null) {
+                                                                       WidgetMouseLeave (imlVE.HoverWidget, e);
+                                                                       imlVE.HoverWidget = imlVE.HoverWidget.LogicalParent as GraphicObject;
+                                                               }
+
+                                                               WidgetCheckOver (GraphicTree [i], e);
+                                                               return true;
+                                                       }
+                                               }
+                                               i++;
+                                       }
+                               }
+
+
+                               if (imlVE.HoverWidget.MouseIsIn (e.Position)) {
+                                       WidgetCheckOver (imlVE.HoverWidget, (e));
+                                       return true;
+                               } else {
+                                       WidgetMouseLeave (imlVE.HoverWidget, e);
+                                       //seek upward from last focused graph obj's
+                                       while (imlVE.HoverWidget.LogicalParent as GraphicObject != null) {
+                                               imlVE.HoverWidget = imlVE.HoverWidget.LogicalParent as GraphicObject;
+                                               if (imlVE.HoverWidget.MouseIsIn (e.Position)) {
+                                                       WidgetCheckOver (imlVE.HoverWidget, e);
+                                                       return true;
+                                               } else
+                                                       WidgetMouseLeave (imlVE.HoverWidget, e);
+                                       }
+                               }
+                       }
+
+                       //top level graphic obj's parsing
+                       lock (imlVE.GraphicTree) {
+                               for (int i = 0; i < imlVE.GraphicTree.Count; i++) {
+                                       GraphicObject g = imlVE.GraphicTree [i];
+                                       if (g.MouseIsIn (e.Position)) {
+                                               WidgetCheckOver (g, e);
+                                               return true;
+                                       }
+                               }
+                       }
+                       imlVE.HoverWidget = null;
+                       return false;
+
+               }
+
+               void GTView_SelectedItemChanged (object sender, SelectionChangeEventArgs e)
+               {
+                       SelectedItem = e.NewValue as GraphicObject;
+               }
+       }
+}
diff --git a/CrowIDE/src/Editors/Parsers/BufferParser.cs b/CrowIDE/src/Editors/Parsers/BufferParser.cs
new file mode 100644 (file)
index 0000000..dfec17a
--- /dev/null
@@ -0,0 +1,380 @@
+using System;
+using System.IO;
+using Crow;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+
+namespace Crow.Coding
+{
+       /// <summary>
+       /// base class for tokenizing sources
+       /// </summary>
+       public abstract class BufferParser
+       {
+               /// <summary>
+               /// Default tokens, this enum may be overriden in derived parser with the new keyword,
+               /// see XMLParser for example.
+               /// </summary>
+               public enum TokenType {
+                       Unknown = 0,
+                       WhiteSpace = 1,
+                       NewLine = 2,
+                       LineComment = 3,
+                       BlockCommentStart = 4,
+                       BlockComment = 5,
+                       BlockCommentEnd = 6,
+                       Preprocessor = 7,
+                       Identifier = 8,
+                       Keyword = 9,
+                       OpenBlock = 10,
+                       CloseBlock = 11,
+                       StatementEnding = 12,
+                       OperatorOrPunctuation = 13,
+                       IntegerLitteral = 14,
+                       RealLitteral = 15,
+                       StringLitteralOpening = 16,
+                       StringLitteralClosing = 17,
+                       StringLitteral = 18,
+                       CharLitteralOpening = 19,
+                       CharLitteralClosing = 20,
+                       CharLitteral = 21,
+                       BoolLitteral = 22,
+                       NullLitteral = 23,                       
+                       Type = 24,
+               }
+
+               #region CTOR
+               public BufferParser (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
+
+               internal int currentLine = 0;
+               internal int currentColumn = 0;
+
+               int syntTreeDepth = 0;
+               public int SyntacticTreeDepth {
+                       get { return syntTreeDepth;}
+                       set {
+                               syntTreeDepth = value;
+                               if (syntTreeDepth > SyntacticTreeMaxDepth)
+                                       SyntacticTreeMaxDepth = syntTreeDepth;
+                       }
+               }
+               public int SyntacticTreeMaxDepth = 0;
+
+               protected CodeBuffer buffer;
+               protected Token currentTok;
+               protected bool eol = true;
+               protected Point CurrentPosition {
+                       get { return new Point (currentLine, currentColumn); }
+                       set {
+                               currentLine = value.Y;
+                               currentColumn = value.X;
+                       }
+               }
+
+               public Node RootNode;
+
+               public abstract void ParseCurrentLine();
+               public abstract void SyntaxAnalysis ();
+               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 ParserException)
+                                       SetLineInError (ex as ParserException);
+                       }
+               }
+               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 ParserException)
+                                       SetLineInError (ex as ParserException);
+                       }
+
+               }
+
+               public virtual void SetLineInError(ParserException 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);
+               }
+               public virtual string LineBrkRegex {
+                       get { return @"\r\n|\r|\n|\\\\n"; }
+               }
+               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 ParserException(parser, "closing tag not corresponding"));
+                       //                                      }
+                       //
+                       //                              }
+                       //                      }
+               }
+
+               #region low level parsing
+               protected void addCharToCurTok(char c, Point position){
+                       currentTok.Start = position;
+                       currentTok += c;
+               }
+               /// <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 ();
+               }
+               protected void setPreviousTokOfTypeTo (TokenType inType, TokenType newType) {
+                       for (int i = currentLine; i >= 0; i--) {
+                               int j = buffer [i].Tokens.Count - 1;
+                               while (j >= 0) {
+                                       if (buffer [i].Tokens [j].Type == inType) {
+                                               Token t = buffer [i].Tokens [j];
+                                               t.Type = newType;
+                                               buffer [i].Tokens [j] = t;
+                                               return;
+                                       }
+                                       j--;
+                               }                               
+                       }
+               }
+               /// <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 ParserException (currentLine, currentColumn, "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 ParserException (currentLine, currentColumn, "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;
+               }
+               protected virtual string Read(int charCount){
+                       string tmp = "";
+                       for (int i = 0; i < charCount; i++) {
+                               if (eol)
+                                       break;
+                               tmp += Read ();
+                       }
+                       return tmp;
+               }
+               /// <summary>
+               /// read until end of line is reached
+               /// </summary>
+               /// <returns>string read</returns>
+               protected virtual string ReadLine () {
+                       StringBuilder tmp = new StringBuilder();
+                       char c = Read ();
+                       while (!eol) {
+                               tmp.Append (c);
+                               c = Read ();
+                       }
+                       return tmp.ToString();
+               }
+               /// <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 ParserException (currentLine, currentColumn, "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
+
+               protected Node addChildNode (Node curNode, CodeLine cl, int tokPtr, string type = "") {
+                       Node n = new Node () { Name = cl.Tokens [tokPtr].Content, StartLine = cl, Type = type };
+                       curNode.AddChild (n);
+                       if (cl.SyntacticNode == null)
+                               cl.SyntacticNode = n;
+                       SyntacticTreeDepth++;
+                       return n;
+               }
+               protected void closeNodeAndGoUp (ref Node n, CodeLine cl, string type = ""){
+                       while (n != null) {
+                               if (n.Type == type) {
+                                       n.EndLine = cl;
+                                       n = n.Parent;
+                                       SyntacticTreeDepth--;
+                                       break;
+                               }
+                               n = n.Parent;
+                               SyntacticTreeDepth--;
+                       }
+               }
+               protected void closeNodeAndGoUp (ref Node n, CodeLine cl){
+                       SyntacticTreeDepth--;
+                       n.EndLine = cl;
+                       n = n.Parent;
+               }
+
+               protected void initSyntaxAnalysis () {
+                       RootNode = new Node () { Name = "RootNode", Type="Root" };
+                       SyntacticTreeDepth = SyntacticTreeMaxDepth = 0;
+               }
+
+
+               protected void throwParserException(string msg){
+                       throw new ParserException (currentLine, currentColumn, msg);
+               }
+       }
+}
\ No newline at end of file
diff --git a/CrowIDE/src/Editors/Parsers/CSharpParser.cs b/CrowIDE/src/Editors/Parsers/CSharpParser.cs
new file mode 100644 (file)
index 0000000..62090bc
--- /dev/null
@@ -0,0 +1,384 @@
+using System;
+using Crow;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text.RegularExpressions;
+using System.Linq;
+
+namespace Crow.Coding
+{
+       public class CSharpParser : BufferParser
+       {
+               #region keywords
+               string[] keywords = new string[] {
+                       "abstract",
+                       "as",
+                       "ascending",
+                       "async",
+                       "await",
+                       "base",
+                       "bool",
+                       "break",
+                       "byte",
+                       "case",
+                       "catch",
+                       "char",
+                       "checked",
+                       "class",
+                       "const",
+                       "continue",
+                       "decimal",
+                       "default",
+                       "delegate",
+                       "descending",
+                       "do",
+                       "double",
+                       "dynamic",
+                       "else",
+                       "enum",
+                       "equals",
+                       "event",
+                       "explicit",
+                       "extern",
+                       "false",
+                       "finally",
+                       "fixed",
+                       "float",
+                       "for",
+                       "foreach",
+                       "from",
+                       "get",
+                       "goto",
+                       "group",
+                       "if",
+                       "implicit",
+                       "in",
+                       "int",
+                       "interface",
+                       "internal",
+                       "is",
+                       "join",
+                       "let",
+                       "lock",
+                       "long",
+                       "nameof",
+                       "namespace",
+                       "new",
+                       "null",
+                       "object",
+                       "operator",
+                       "orderby",
+                       "out",
+                       "override",
+                       "params",
+                       "partial",
+                       "private",
+                       "protected",
+                       "public",
+                       "readonly",
+                       "ref",
+                       "return",
+                       "sbyte",
+                       "sealed",
+                       "select",
+                       "set",
+                       "short",
+                       "sizeof",
+                       "stackalloc",
+                       "static",
+                       "string",
+                       "struct",
+                       "switch",
+                       "this",
+                       "throw",
+                       "true",
+                       "try",
+                       "typeof",
+                       "uint",
+                       "ulong",
+                       "unchecked",
+                       "unsafe",
+                       "ushort",
+                       "using",
+                       "value",
+                       "var",
+                       "virtual",
+                       "void",
+                       "volatile",
+                       "when",
+                       "where",
+                       "while",
+                       "yield "                        
+               };
+               #endregion
+
+               public enum States
+               {
+                       init,       
+                       BlockComment,
+                       InNameSpace,
+                       InClass,
+                       InMember,
+                       Unknown,
+               }
+
+               public CSharpParser (CodeBuffer _buffer) : base(_buffer)
+               {
+               }
+
+               #region Regular Expression for validity checks
+               static Regex rxValidChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}");
+               static Regex rxNameStartChar = new Regex(@"_|\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}");
+               static Regex rxNameChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}");
+               static Regex rxNewLineChar = new Regex(@"\u000D|\u000A|\u0085|\u2028|\u2029");
+               static Regex rxWhiteSpaceChar = new Regex(@"\p{Zs}|\u0009|\u000B|\u000C");
+               static Regex rxDecimal = new Regex(@"[0-9]+");
+               static Regex rxHexadecimal = new Regex(@"[0-9a-fA-F]+");
+
+               public static bool CharIsValidCharStartName (char c) {
+                       return rxNameStartChar.IsMatch(new string(new char[]{c}));
+               }
+               public static bool CharIsValidCharName (char c) {
+                       return rxNameChar.IsMatch(new string(new char[]{c}));
+               }
+
+               public bool nextCharIsValidCharStartName
+               {
+                       get { return CharIsValidCharStartName(Peek()); }
+               }
+               public bool nextCharIsValidCharName
+               {
+                       get { return CharIsValidCharName(Peek()); }
+               }
+               #endregion
+
+               States curState = States.init;
+               States savedState = 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) {
+                               if (currentTok.IsNull)
+                                       SkipWhiteSpaces ();
+
+                               if (curState == States.BlockComment) {
+                                       currentTok.Start = CurrentPosition;
+                                       currentTok.Type = (BufferParser.TokenType)TokenType.BlockComment;
+                                       currentTok += ReadLineUntil ("*/");
+                                       if (Peek (2) == "*/") {
+                                               readToCurrTok (2);
+                                               curState = savedState;
+                                       }
+                                       saveAndResetCurrentTok ();
+                                       continue;
+                               }
+
+                               switch (Peek()) {
+                               case '\n':
+                                       eol = true;
+                                       if (!currentTok.IsNull)
+                                               saveAndResetCurrentTok ();
+                                       break;
+                               case '#':
+                                       readToCurrTok (true);
+                                       currentTok += ReadLine ();
+                                       saveAndResetCurrentTok (TokenType.Preprocessor);
+                                       break;
+                               case '/':
+                                       readToCurrTok (true);
+                                       switch (Peek ()) {
+                                       case '*':
+                                               readToCurrTok ();
+                                               currentTok += ReadLine ();
+                                               //currentTok.Type = (Parser.TokenType)TokenType.BlockComment;
+                                               savedState = curState;
+                                               curState = States.BlockComment;
+                                               saveAndResetCurrentTok (TokenType.BlockComment);
+                                               break;
+                                       case '/':
+                                               //readToCurrTok ();
+                                               currentTok += ReadLine ();
+                                               saveAndResetCurrentTok (TokenType.LineComment);
+                                               //currentTok.Type = (Parser.TokenType)TokenType.LineComment;
+                                               break;
+                                       default:
+                                               currentTok += ReadLine ();
+                                               saveAndResetCurrentTok (TokenType.Unknown);
+                                               break;
+                                       }
+                                       break;
+                               case '{':
+                                       if (currentTok.IsNull)
+                                               readAndResetCurrentTok (TokenType.OpenBlock, true);
+                                       else
+                                               readToCurrTok ();
+                                       break;
+                               case '}':
+                                       if (currentTok.IsNull)
+                                               readAndResetCurrentTok (TokenType.CloseBlock, true);
+                                       else
+                                               readToCurrTok ();                                       
+                                       break;
+                               case '\\'://unicode escape sequence
+                                       if (!(currentTok.Type == TokenType.Identifier ||
+                                           currentTok.IsEmpty || currentTok.Type == TokenType.StringLitteral || currentTok.Type == TokenType.CharLitteral)) {
+                                               saveAndResetCurrentTok ();
+                                       }
+                                       Point pos = CurrentPosition;
+                                       Read ();
+                                       char escChar = Read ();
+
+                                       if (escChar == 'u') {
+                                               char c = char.ConvertFromUtf32 (int.Parse (Read (4), System.Globalization.NumberStyles.HexNumber))[0];
+                                               if (currentTok.IsEmpty) {
+                                                       if (!CharIsValidCharStartName (c))
+                                                               throwParserException ("expecting identifier start");                                                    
+                                                       currentTok.Start = pos;
+                                                       currentTok.Type = TokenType.Identifier;
+                                               } else if (currentTok.Type == TokenType.Identifier) {
+                                                       if (!CharIsValidCharName (c))
+                                                               throwParserException ("expecting identifier valid char");                                               
+                                               }
+                                               currentTok += c;
+                                               break;
+                                       }
+                                       currentTok += new String (new char[] { '\\', escChar });
+                                       break;
+                               case '\'':
+                                       if (currentTok.IsNull) {
+                                               readAndResetCurrentTok (TokenType.CharLitteralOpening, true);
+                                               currentTok.Type = TokenType.CharLitteral;
+                                       } else if (currentTok.Type == TokenType.CharLitteral) {
+                                               saveAndResetCurrentTok ();
+                                               readAndResetCurrentTok (TokenType.CharLitteralClosing, true);
+                                       } else if (currentTok.Type == TokenType.StringLitteral){
+                                               readToCurrTok ();
+                                       } else
+                                               throwParserException ("unexpected character: (\')");                                            
+                                       break;
+                               case '"':
+                                       if (currentTok.IsNull) {
+                                               readAndResetCurrentTok (TokenType.StringLitteralOpening, true);
+                                               currentTok.Type = TokenType.StringLitteral;
+                                       } else if (currentTok.Type == TokenType.StringLitteral) {
+                                               saveAndResetCurrentTok ();
+                                               readAndResetCurrentTok (TokenType.StringLitteralClosing, true);
+                                       } else
+                                               throwParserException ("unexpected character: (\")");
+                                       break;
+                               default:
+                                       if (currentTok.Type == TokenType.StringLitteral || currentTok.Type == TokenType.CharLitteral) {
+                                               readToCurrTok (currentTok.IsEmpty);
+                                       } else if (currentTok.IsNull) {
+                                               if (nextCharIsValidCharStartName) {                                             
+                                                       readToCurrTok (true);
+                                                       while (nextCharIsValidCharName)
+                                                               readToCurrTok ();
+
+                                                       if (keywords.Contains (currentTok.Content))
+                                                               saveAndResetCurrentTok (TokenType.Keyword);
+                                                       else
+                                                               saveAndResetCurrentTok (TokenType.Identifier);
+                                                       continue;
+                                               } else
+                                                       readAndResetCurrentTok(TokenType.Unknown, true);
+                                       } else
+                                               readAndResetCurrentTok(TokenType.Unknown, true);                                        
+                                       break;
+                               }
+                       }
+
+                       if (cl.EndingState != (int)curState && currentLine < buffer.LineCount - 1)
+                               buffer [currentLine + 1].Tokens = null;
+
+                       cl.EndingState = (int)curState;
+               }
+               
+               public override void SyntaxAnalysis ()
+               {
+                       initSyntaxAnalysis ();
+                       Node currentNode = RootNode;
+
+                       int ptrLine = 0;
+                       while (ptrLine < buffer.LineCount) {
+                               CodeLine cl = buffer [ptrLine];
+                               if (cl.Tokens == null){
+                                       ptrLine++;
+                                       continue;
+                               }
+                               cl.SyntacticNode = null;
+
+                               int tokPtr = 0;
+                               bool onlyWhiteSpace = true;
+                               while (tokPtr < cl.Tokens.Count) {
+                                       if (cl.Tokens [tokPtr].Type == TokenType.WhiteSpace) {
+                                               tokPtr++;
+                                               continue;
+                                       }
+
+                                       if (cl.Tokens [tokPtr].Type == TokenType.LineComment && onlyWhiteSpace) {
+                                               int startLine = ptrLine;
+                                               ptrLine++;
+                                               while (ptrLine < buffer.LineCount) {
+                                                       int idx = buffer [ptrLine].FirstNonBlankTokIndex;
+                                                       if (idx < 0) 
+                                                               break;
+                                                       if (buffer [ptrLine].Tokens [idx].Type != TokenType.LineComment)
+                                                               break;
+                                                       ptrLine++;
+                                               }
+                                               ptrLine--;
+                                               if (ptrLine - startLine > 0) {
+                                                       currentNode = addChildNode (currentNode, cl, tokPtr, "comment");
+                                                       closeNodeAndGoUp (ref currentNode, buffer [ptrLine], "comment");
+                                               }
+                                               break;
+                                       }
+
+                                       switch (cl.Tokens [tokPtr].Type) {
+                                       case TokenType.OpenBlock:
+                                               currentNode = addChildNode (currentNode, cl, tokPtr);
+                                               break;
+                                       case TokenType.CloseBlock:                                              
+                                               closeNodeAndGoUp (ref currentNode, cl);
+                                               break;
+                                       case TokenType.Preprocessor:
+                                               if (cl.Tokens [tokPtr].Content.StartsWith ("#region")) {
+                                                       currentNode = addChildNode (currentNode, cl, tokPtr, "region");
+                                               } else if (cl.Tokens [tokPtr].Content.StartsWith ("#endregion")) {
+                                                       
+                                                       closeNodeAndGoUp (ref currentNode, cl,"region");
+                                               }
+                                               break;
+                                       }
+                                       onlyWhiteSpace = false;
+                                       tokPtr++;
+                               }
+                               ptrLine++;
+                       }
+                       ptrLine = 0;
+                       while (ptrLine < buffer.LineCount) {
+                               CodeLine cl = buffer [ptrLine];
+                               if (cl.IsFoldable) {
+                                       if (cl.SyntacticNode.Type == "comment" || cl.SyntacticNode.Type == "region")
+                                               cl.IsFolded = true;
+                               }
+                               ptrLine++;
+                       }
+               }
+       }
+}
+
diff --git a/CrowIDE/src/Editors/Parsers/StyleParser.cs b/CrowIDE/src/Editors/Parsers/StyleParser.cs
new file mode 100644 (file)
index 0000000..9a1e74c
--- /dev/null
@@ -0,0 +1,179 @@
+using System;
+using Crow;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text.RegularExpressions;
+using System.Linq;
+
+namespace Crow.Coding
+{
+       public class StyleParser : BufferParser
+       {
+               enum States { init, classNames, members, value, endOfStatement }
+
+               public StyleParser (CodeBuffer _buffer) : base(_buffer)
+               {
+               }
+
+               #region Character ValidityCheck
+               static Regex rxValidChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}");
+               static Regex rxNameStartChar = new Regex(@"_|\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}");                                                                                                                      
+               static Regex rxNameChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}");
+               static Regex rxDecimal = new Regex(@"[0-9]+");
+               static Regex rxHexadecimal = new Regex(@"[0-9a-fA-F]+");
+
+               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
+
+               States curState = States.classNames;
+
+               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 ParserException (currentLine, currentColumn, "Unexpected end of line");
+                                       Read ();
+                                       eol = true;
+                                       continue;
+                               }
+
+                               switch (Peek()) {
+                               case '/':
+                                       readToCurrTok (true);
+                                       switch (Peek ()) {
+                                       case '/':
+                                               currentTok += ReadLine ();
+                                               saveAndResetCurrentTok (TokenType.LineComment);
+                                               break;
+                                       default:
+                                               currentTok += ReadLine ();
+                                               saveAndResetCurrentTok (TokenType.Unknown);
+                                               break;
+                                       }
+                                       break;
+                               case ',':
+                                       if (curState != States.init && curState != States.classNames )
+                                               throw new ParserException (currentLine, currentColumn, "Unexpected char ','");
+                                       readAndResetCurrentTok (TokenType.OperatorOrPunctuation, true);
+                                       curState = States.classNames;
+                                       break;
+                               case '{':
+                                       if (!(curState == States.init || curState == States.classNames))
+                                               throw new ParserException (currentLine, currentColumn, "Unexpected char '{'");
+                                       readAndResetCurrentTok (TokenType.OpenBlock, true);
+                                       curState = States.members;
+                                       break;
+                               case '}':
+                                       if (curState != States.members)
+                                               throw new ParserException (currentLine, currentColumn, "Unexpected char '}'");
+                                       readAndResetCurrentTok (TokenType.CloseBlock, true);
+                                       curState = States.classNames;
+                                       break;
+                               case '=':
+                                       if (curState == States.classNames)
+                                               throw new ParserException (currentLine, currentColumn, "Unexpected char '='");
+                                       setPreviousTokOfTypeTo (TokenType.Type, TokenType.Identifier);
+                                       readAndResetCurrentTok (TokenType.OperatorOrPunctuation, true);
+                                       curState = States.value;
+                                       break;
+                               case '"':
+                                       if (curState != States.value)
+                                               throw new ParserException (currentLine, currentColumn, "Unexpected char '\"'");                                 
+                                       readAndResetCurrentTok (TokenType.StringLitteralOpening, true);
+
+                                       while (!eol) {
+                                               currentTok += ReadLineUntil ("\"");
+                                               if (currentTok.Content [currentTok.Content.Length - 1] == '\\')
+                                                       readToCurrTok ();
+                                               else
+                                                       break;
+                                       }
+                                       if (eol)
+                                               throw new ParserException (currentLine, currentColumn, "Unexpected end of line");
+                                       saveAndResetCurrentTok (TokenType.StringLitteral);
+
+                                       readAndResetCurrentTok (TokenType.StringLitteralClosing, true);
+                                       curState = States.endOfStatement;
+                                       break;
+                               case ';':
+                                       if (curState != States.endOfStatement)
+                                               throw new ParserException (currentLine, currentColumn, "Unexpected end of statement");                                  
+                                       readAndResetCurrentTok (TokenType.StatementEnding, true);
+                                       curState = States.members;
+                                       break;
+                               default:
+                                       if (currentTok.Type != TokenType.Unknown)
+                                               throw new ParserException (currentLine, currentColumn, "error curtok not null");
+                                       if (curState == States.value)
+                                               throw new ParserException (currentLine, currentColumn, "expecting value enclosed in '\"'");
+                                       if (curState == States.endOfStatement)
+                                               throw new ParserException (currentLine, currentColumn, "expecting end of statement");                                   
+                                       
+                                       if (nextCharIsValidCharStartName) {                                             
+                                               readToCurrTok (true);
+                                               while (nextCharIsValidCharName)
+                                                       readToCurrTok ();
+                                       }
+                                       saveAndResetCurrentTok (TokenType.Type);
+                                       break;
+                               }
+                       }
+
+                       if (cl.EndingState != (int)curState && currentLine < buffer.LineCount - 1)
+                               buffer [currentLine + 1].Tokens = null;
+
+                       cl.EndingState = (int)curState;
+               }
+               public override void SyntaxAnalysis ()
+               {
+                       initSyntaxAnalysis ();
+                       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 (cl.Tokens [tokPtr].Type) {
+                                       case TokenType.OpenBlock:                                               
+                                               currentNode = addChildNode (currentNode, cl, tokPtr, "style");
+                                               break;
+                                       case TokenType.CloseBlock:                                              
+                                               closeNodeAndGoUp (ref currentNode, cl, "style");
+                                               break;
+                                       }
+                                       tokPtr++;
+                               }
+                       }
+               }
+       }
+}
+
diff --git a/CrowIDE/src/Editors/Parsers/XMLParser.cs b/CrowIDE/src/Editors/Parsers/XMLParser.cs
new file mode 100644 (file)
index 0000000..d31e102
--- /dev/null
@@ -0,0 +1,298 @@
+using System;
+using Crow;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Diagnostics;
+using System.Linq;
+
+namespace Crow.Coding
+{
+       public class XMLParser : BufferParser
+       {
+               public new enum TokenType {
+                       Unknown = BufferParser.TokenType.Unknown,
+                       WhiteSpace = BufferParser.TokenType.WhiteSpace,
+                       NewLine = BufferParser.TokenType.NewLine,
+                       LineComment = BufferParser.TokenType.LineComment,
+                       BlockCommentStart = BufferParser.TokenType.BlockCommentStart,
+                       BlockComment = BufferParser.TokenType.BlockComment,
+                       BlockCommentEnd = BufferParser.TokenType.BlockCommentEnd,
+                       ElementName = BufferParser.TokenType.Identifier,
+                       AttributeName = BufferParser.TokenType.Keyword,
+                       ElementClosing = BufferParser.TokenType.StatementEnding,
+                       Affectation = BufferParser.TokenType.OperatorOrPunctuation,
+                       AttributeValueOpening = BufferParser.TokenType.StringLitteralOpening,
+                       AttributeValueClosing = BufferParser.TokenType.StringLitteralClosing,
+                       AttributeValue = BufferParser.TokenType.StringLitteral,
+                       XMLDecl = BufferParser.TokenType.Preprocessor,
+                       ElementStart = 50,
+                       ElementEnd = 51,
+               }
+
+               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 (ParserException 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 ParserException (currentLine, currentColumn, "Unexpected end of line");
+                                       Read ();
+                                       eol = true;
+                                       continue;
+                               }
+
+                               if (curState == States.BlockComment) {
+                                       if (currentTok != TokenType.Unknown)
+                                               Debugger.Break ();
+
+                                       currentTok.Start = CurrentPosition;
+                                       currentTok.Type = (BufferParser.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 ParserException (currentLine, currentColumn, "xml decl may appear only on first line");
+                                               readToCurrTok ();
+                                               currentTok += ReadLineUntil ("?>");
+                                               if (Peek (2) != "?>")
+                                                       throw new ParserException (currentLine, currentColumn, "expecting '?>'");
+                                               readToCurrTok (2);
+                                               saveAndResetCurrentTok (TokenType.XMLDecl);
+                                               curState = States.prolog;
+                                               break;
+                                       case '!':
+                                               readToCurrTok ();
+                                               switch (Peek()) {
+                                               case '-':
+                                                       readToCurrTok ();
+                                                       if (Peek () != '-')
+                                                               throw new ParserException (currentLine, currentColumn, "Expecting comment start tag");
+                                                       readToCurrTok ();
+                                                       currentTok += ReadLineUntil ("--");
+                                                       if (Peek (3) == "-->") {
+                                                               readToCurrTok (3);
+                                                       }else
+                                                               curState = States.BlockComment;
+                                                       saveAndResetCurrentTok (TokenType.BlockComment);
+                                                       break;
+                                               default:
+                                                       throw new ParserException (currentLine, currentColumn, "error");
+                                               }
+                                               break;
+                                       default:
+                                               if (!(curState == States.Content || curState == States.XML || curState == States.init || curState == States.prolog))
+                                                       throw new ParserException (currentLine, currentColumn, "Unexpected char: '<'");
+                                               if (Peek () == '/') {
+                                                       curState = States.EndTag;
+                                                       readToCurrTok ();
+                                                       saveAndResetCurrentTok (TokenType.ElementEnd);
+                                               } else {
+                                                       curState = States.StartTag;
+                                                       saveAndResetCurrentTok (TokenType.ElementStart);
+                                               }
+
+                                               if (!nextCharIsValidCharStartName)
+                                                       throw new ParserException (currentLine, currentColumn, "Expected element name");
+
+                                               readToCurrTok (true);
+                                               while (nextCharIsValidCharName)
+                                                       readToCurrTok ();
+
+                                               saveAndResetCurrentTok (TokenType.ElementName);
+                                               break;
+                                       }
+                                       break;
+                               case '/':
+                                       if (curState != States.StartTag)
+                                               throw new ParserException (currentLine, currentColumn, "Unexpected char: '/'");
+                                       readToCurrTok (true);
+                                       if (Peek () != '>')
+                                               throw new ParserException (currentLine, currentColumn, "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 ParserException (currentLine, currentColumn, "Unexpected char: '>'");
+                                       }
+                                       break;
+                               default:
+                                       switch (curState) {
+                                       case States.StartTag:
+                                               if (!nextCharIsValidCharStartName)
+                                                       throw new ParserException (currentLine, currentColumn, "Expected attribute name");
+                                               readToCurrTok (true);
+                                               while (nextCharIsValidCharName)
+                                                       readToCurrTok ();
+                                               saveAndResetCurrentTok (TokenType.AttributeName);
+
+                                               SkipWhiteSpaces ();
+
+                                               if (Peek () != '=')
+                                                       throw new ParserException (currentLine, currentColumn, "Expecting: '='");
+                                               readAndResetCurrentTok (TokenType.Affectation, true);
+
+                                               SkipWhiteSpaces ();
+
+                                               char openAttVal = Peek ();
+                                               if (openAttVal != '"' && openAttVal != '\'')
+                                                       throw new ParserException (currentLine, currentColumn, "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 ParserException (currentLine, currentColumn, string.Format ("Expecting {0}", openAttVal));
+                                               readAndResetCurrentTok (TokenType.AttributeValueClosing, true);
+                                               break;
+                                       default:
+                                               throw new ParserException (currentLine, currentColumn, "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 ()
+               {
+                       initSyntaxAnalysis ();
+                       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++;
+                                               currentNode = addChildNode (currentNode, cl, tokPtr, "Element");
+                                               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 ParserException (currentLine, currentColumn, "Closing tag mismatch");
+                                               }
+                                               closeNodeAndGoUp (ref currentNode, cl, "Element");
+                                               break;
+                                       case TokenType.ElementClosing:
+                                               //currentNode = currentNode.Parent;
+                                               break;
+                                       default:
+                                               break;
+                                       }
+                                       tokPtr++;
+                               }
+                       }
+               }
+       }
+}
+
diff --git a/CrowIDE/src/Editors/SvgEditor.cs b/CrowIDE/src/Editors/SvgEditor.cs
new file mode 100644 (file)
index 0000000..219eea6
--- /dev/null
@@ -0,0 +1,137 @@
+//
+// SvgEditor.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.ComponentModel;
+using Cairo;
+
+namespace Crow.Coding
+{
+       public class SvgEditor : Editor
+       {
+               SvgPicture _pic = new SvgPicture();
+
+               int zoom;
+
+               [DefaultValue(100)]
+               public int Zoom {
+                       get { return zoom; }
+                       set {
+                               if (zoom == value)
+                                       return;
+                               zoom = value;
+                               NotifyValueChanged ("Zoom", zoom);
+                               updateMaxScrolls ();
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+
+               void updateMaxScrolls() {                       
+                       MaxScrollX = Math.Max(0, _pic.Dimensions.Width * zoom / 100 - Slot.Width);
+                       MaxScrollY = Math.Max(0, _pic.Dimensions.Height * zoom / 100 - Slot.Height);
+
+                       if (Slot.Width + MaxScrollX > 0)
+                               NotifyValueChanged ("ChildWidthRatio", Slot.Width * Slot.Width / (Slot.Width + MaxScrollX));
+                       else
+                               NotifyValueChanged ("ChildWidthRatio", 0);
+                       
+                       if (Slot.Height + MaxScrollY > 0)
+                               NotifyValueChanged ("ChildHeightRatio", Slot.Height * Slot.Height / (Slot.Height + MaxScrollY));
+                       else
+                               NotifyValueChanged ("ChildHeightRatio", 0);
+               }
+               #region editor overrides
+               protected override void updateEditorFromProjFile ()
+               {
+                       Error = null;
+                       try {
+                               editorMutex.EnterWriteLock();
+                               _pic.LoadSvgFragment (projFile.Source);
+                               _pic.Scaled = true;
+                               _pic.KeepProportions = true;
+                       } catch (Exception ex) {
+                               Error = ex;
+                       }
+                       editorMutex.ExitWriteLock ();
+                       updateMaxScrolls ();
+                       RegisterForGraphicUpdate ();
+               }
+               protected override void updateProjFileFromEditor ()
+               {
+                       throw new NotImplementedException ();
+               }
+               protected override bool EditorIsDirty {
+                       get { return false;     }
+                       set {
+                               throw new NotImplementedException ();
+                       }
+               }
+               #endregion
+
+               #region GraphicObject overrides
+               protected override int measureRawSize (LayoutingType lt)
+               {
+                       if (_pic == null)
+                               return 2 * Margin;
+                       //_pic = "#Crow.Images.Icons.IconAlerte.svg";
+                       //TODO:take scalling in account
+                       if (lt == LayoutingType.Width)
+                               return _pic.Dimensions.Width + 2 * Margin;
+                       else
+                               return _pic.Dimensions.Height + 2 * Margin;
+               }
+               protected override void onDraw (Context gr)
+               {
+                       base.onDraw (gr);
+
+                       Rectangle r = ClientRectangle;
+                       Foreground.SetAsSource (gr, r);
+                       gr.Rectangle (r, 0.1);
+                       gr.Stroke ();
+
+                       r.Width = _pic.Dimensions.Width * zoom / 100;
+                       r.Height = _pic.Dimensions.Height * zoom / 100;
+
+                       gr.Save ();
+
+                       editorMutex.EnterReadLock ();
+
+                       gr.Translate (-ScrollX, -ScrollY);
+                       if (_pic != null)
+                               _pic.Paint (gr, r);
+                       editorMutex.ExitReadLock ();
+
+                       gr.Restore ();
+               }
+               public override void OnLayoutChanges (LayoutingType layoutType)
+               {
+                       base.OnLayoutChanges (layoutType);
+                       if ((layoutType | LayoutingType.Sizing) > 0)
+                               updateMaxScrolls ();
+               }
+               #endregion
+       }
+}
+
index 0d12fec8d514007ce00965db7c4ace97f00293b8..05ef71e4f73c627b76a04c9ca5dc5f602a8b7fac 100644 (file)
@@ -25,6 +25,9 @@ namespace Crow
 {
        public static partial class Extensions
        {
+               public static string GetIcon(this GraphicObject go){
+                       return "#Crow.Coding.icons.toolbox." + go.GetType().FullName + ".svg";
+               }
                public static List<GraphicObject> GetChildren(this GraphicObject go){
                        Type goType = go.GetType();
                        if (typeof (Group).IsAssignableFrom (goType))
index c8e1a70f38178134a5d51573580fec9285e4a256..e7776d26a563cdd0ad1662ccb63a78ac79d2924c 100644 (file)
@@ -52,7 +52,7 @@ namespace Crow.Coding
                                go.IFace.DragImageHeight = dis;
                                go.IFace.DragImageWidth = dis;
                                SvgPicture pic = new SvgPicture ();
-                               pic.Load (IconPath);
+                               pic.Load (go.IFace, IconPath);
                                ImageSurface img = new ImageSurface (Format.Argb32, dis, dis);
                                using (Context ctx = new Context (img)) {
                                        Rectangle r = new Rectangle (0, 0, dis, dis);
diff --git a/CrowIDE/src/ImlVisualEditor.cs b/CrowIDE/src/ImlVisualEditor.cs
deleted file mode 100644 (file)
index d084904..0000000
+++ /dev/null
@@ -1,506 +0,0 @@
-//
-//  ImlVisualEditor.cs
-//
-//  Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-//  Copyright (c) 2016 jp
-//
-//  This program is free software: you can redistribute it and/or modify
-//  it under the terms of the GNU General Public License as published by
-//  the Free Software Foundation, either version 3 of the License, or
-//  (at your option) any later version.
-//
-//  This program is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
-//
-//  You should have received a copy of the GNU General Public License
-//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-using System;
-using Crow;
-using System.Threading;
-using System.Xml.Serialization;
-using System.ComponentModel;
-using System.IO;
-using System.Collections.Generic;
-using Crow.IML;
-using System.Text;
-using System.Xml;
-
-namespace Crow.Coding
-{
-       public class ImlVisualEditor : Editor
-       {
-               #region CTOR
-               public ImlVisualEditor () : base()
-               {
-                       imlVE = new DesignInterface ();
-               }
-               #endregion
-
-               DesignInterface imlVE;
-               GraphicObject selectedItem;
-               ImlProjectItem imlProjFile;
-               Exception imlError = null;
-
-               bool drawGrid, snapToGrid;
-               int gridSpacing;
-
-               [DefaultValue(true)]
-               public bool DrawGrid {
-                       get { return drawGrid; }
-                       set {
-                               if (drawGrid == value)
-                                       return;
-                               drawGrid = value;
-                               NotifyValueChanged ("DrawGrid", drawGrid);
-                               RegisterForRedraw ();
-                       }
-               }
-               [DefaultValue(true)]
-               public bool SnapToGrid {
-                       get { return snapToGrid; }
-                       set {
-                               if (snapToGrid == value)
-                                       return;
-                               snapToGrid = value;
-                               NotifyValueChanged ("SnapToGrid", snapToGrid);
-                       }
-               }
-               [DefaultValue(10)]
-               public int GridSpacing {
-                       get { return gridSpacing; }
-                       set {
-                               if (gridSpacing == value)
-                                       return;
-                               gridSpacing = value;
-                               NotifyValueChanged ("GridSpacing", gridSpacing);
-                               RegisterForRedraw ();
-                       }
-               }
-               [XmlAttributeAttribute]public GraphicObject SelectedItem {
-                       get { return selectedItem; }
-                       set {
-                               if (selectedItem == value)
-                                       return;
-                               selectedItem = value;
-                               NotifyValueChanged ("SelectedItem", selectedItem);
-                               RegisterForRedraw ();
-                       }
-               }
-               /// <summary>PoinprojFilever the widget</summary>
-               public virtual GraphicObject HoverWidget
-               {
-                       get { return imlVE.HoverWidget; }
-                       set {
-                               if (HoverWidget == value)
-                                       return;
-                               
-                               imlVE.HoverWidget = value;
-
-                               NotifyValueChanged ("HoverWidget", HoverWidget);
-                       }
-               }
-               [XmlIgnore]public List<LQIList> LQIs {
-                       get { return imlVE.LQIs; }
-               }
-
-               public override ProjectFile ProjectNode {
-                       get {
-                               return base.ProjectNode;
-                       }
-                       set {
-                               base.ProjectNode = value;
-                               imlProjFile = projFile as ImlProjectItem;
-                               imlVE.ProjFile = imlProjFile;
-                       }
-               }
-
-               public List<GraphicObject> GraphicTree {
-                       get { return imlVE.GraphicTree; }
-               }
-               protected override void updateProjFileFromEditor ()
-               {
-                       try {
-                               projFile.UpdateSource(this, imlProjFile.Instance.GetIML());
-                       } catch (Exception ex) {
-                               Error = ex.InnerException;
-                               if (Monitor.IsEntered(imlVE.UpdateMutex))
-                                       Monitor.Exit (imlVE.UpdateMutex);
-                       }
-               }
-               protected override void updateEditorFromProjFile () {
-                       try {
-                               string selItemDesignID = null;
-                               if (SelectedItem!=null)
-                                       selItemDesignID = SelectedItem.design_id;
-                               imlVE.ClearInterface();
-                               Instantiator.NextInstantiatorID = 0;
-                               imlVE.Styling = projFile.Project.solution.Styling;
-                               imlVE.DefaultValuesLoader.Clear();
-                               imlVE.DefaultTemplates = projFile.Project.solution.DefaultTemplates;
-                               imlVE.Instantiators = new Dictionary<string, Instantiator>();
-
-                               //prevent error on empty file
-                               bool emptyFile = true;
-                               string src = projFile.Source;
-                               using (Stream s = new MemoryStream (Encoding.UTF8.GetBytes (src))) {
-                                       using (XmlReader itr = XmlReader.Create (s)) {
-                                               while(itr.Read()){
-                                                       if (itr.NodeType == XmlNodeType.Element){
-                                                               emptyFile = false;
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                               }
-                               GraphicObject go = null;
-                               Error = null;
-
-                               if (emptyFile){
-                                       imlProjFile.Instance = null;
-                               }else{
-                                       imlVE.LoadIMLFragment(src);
-                                       imlProjFile.Instance = imlVE.GraphicTree[0];
-                                       if (selItemDesignID!=null)
-                                               imlProjFile.Instance.FindByDesignID(selItemDesignID,out go);                                            
-
-                               }
-                               SelectedItem = go;
-                       } catch (Exception ex) {
-                               Error = ex.InnerException;
-                               if (Monitor.IsEntered(imlVE.UpdateMutex))
-                                       Monitor.Exit (imlVE.UpdateMutex);
-                       }
-               }
-
-               protected override bool EditorIsDirty {
-                       get { return (bool)imlProjFile.Instance?.design_HasChanged; }
-                       set {
-                               if (GraphicTree [0] != null)
-                                       GraphicTree [0].design_HasChanged = value;                      
-                       }
-               }
-               protected override bool IsReady {
-                       get { return imlVE != null && imlProjFile != null; }
-               }
-               protected override void updateCheckPostProcess ()
-               {
-                       imlVE.Update ();
-                       bool isDirty = false;
-
-                       lock (imlVE.RenderMutex)
-                               isDirty = imlVE.IsDirty;
-
-                       if (isDirty) {
-                               lock (IFace.UpdateMutex)
-                                       RegisterForRedraw ();
-                       }
-               }
-
-               #region GraphicObject overrides
-               public override void OnLayoutChanges (LayoutingType layoutType)
-               {
-                       base.OnLayoutChanges (layoutType);
-                       switch (layoutType) {
-                       case LayoutingType.Width:
-                       case LayoutingType.Height:
-                               imlVE.ProcessResize (this.ClientRectangle.Size);
-                               break;
-                       }
-               }
-
-               public override void onMouseMove (object sender, MouseMoveEventArgs e)
-               {
-                       base.onMouseMove (sender, e);
-
-                       GraphicObject oldHW = HoverWidget;
-                       Rectangle scr = this.ScreenCoordinates (this.getSlot ());
-                       ProcessMouseMove (e.X - scr.X, e.Y - scr.Y);
-
-                       if (oldHW == HoverWidget)
-                               return;
-
-                       if (draggedObj != null) {
-                               if (isPossibleContainer (HoverWidget) && draggedObjContainer != HoverWidget) {
-                                       removeDraggedObjFrom ();
-                                       tryAddDraggedObjTo (HoverWidget);
-                               }
-                       }
-
-                       RegisterForRedraw ();
-
-               }
-               public override void onMouseDown (object sender, MouseButtonEventArgs e)
-               {
-                       //base.onMouseDown (sender, e);
-                       SelectedItem = HoverWidget;
-
-                       if (SelectedItem != null && projFile != null) {
-                               projFile.CurrentLine = SelectedItem.design_line;
-                               projFile.CurrentColumn = SelectedItem.design_column;
-                       }
-
-               }
-
-               protected override void onDraw (Cairo.Context gr)
-               {
-                       base.onDraw (gr);
-                       if (!drawGrid)
-                               return;
-
-
-                       Rectangle cb = ClientRectangle;
-                       const double gridLineWidth = 0.1;
-                       double glhw = gridLineWidth / 2.0;
-                       int nbLines = cb.Width / gridSpacing ;
-                       double d = cb.Left + gridSpacing;
-                       for (int i = 0; i < nbLines; i++) {
-                               gr.MoveTo (d-glhw, cb.Y);
-                               gr.LineTo (d-glhw, cb.Bottom);
-                               d += gridSpacing;
-                       }
-                       nbLines = cb.Height / gridSpacing;
-                       d = cb.Top + gridSpacing;
-                       for (int i = 0; i < nbLines; i++) {
-                               gr.MoveTo (cb.X, d - glhw);
-                               gr.LineTo (cb.Right, d -glhw);
-                               d += gridSpacing;
-                       }
-                       gr.LineWidth = gridLineWidth;
-                       Foreground.SetAsSource (gr, cb);
-                       gr.Stroke ();
-
-                       lock (imlVE.RenderMutex) {
-                               using (Cairo.Surface surf = new Cairo.ImageSurface (imlVE.bmp, Cairo.Format.Argb32,
-                                       imlVE.ClientRectangle.Width, imlVE.ClientRectangle.Height, imlVE.ClientRectangle.Width * 4)) {
-                                       gr.SetSourceSurface (surf, cb.Left, cb.Top);
-                                       gr.Paint ();
-                               }
-                               imlVE.IsDirty = false;
-                       }
-
-                       Rectangle hr;
-                       if (HoverWidget != null) {
-                               hr = HoverWidget.ScreenCoordinates (HoverWidget.getSlot ());
-//                     gr.SetSourceColor (Color.LightGray);
-//                     gr.DrawCote (new Cairo.PointD (hr.X, hr.Center.Y), new Cairo.PointD (hr.Right, hr.Center.Y));
-//                     gr.DrawCote (new Cairo.PointD (hr.Center.X, hr.Y), new Cairo.PointD (hr.Center.X, hr.Bottom));
-                               //hr.Inflate (2);
-                               gr.SetSourceColor (Color.LightGray);
-                               gr.SetDash (new double[]{ 3.0, 3.0 }, 0.0);
-                               gr.Rectangle (hr, 1.0);
-                       }
-
-                       if (SelectedItem?.Parent == null)
-                               return;
-                       hr = SelectedItem.ScreenCoordinates(SelectedItem.getSlot ());
-                       hr.Inflate (1);
-                       gr.LineWidth = 2;
-                       gr.SetSourceColor (Color.Yellow);
-                       gr.SetDash (new double[]{ 5.0, 3.0 },0.0);
-                       gr.Rectangle (hr, 1.0);
-               }
-
-               protected override void onDragEnter (object sender, DragDropEventArgs e)
-               {
-                       base.onDragEnter (sender, e);
-                       GraphicObjectDesignContainer godc = e.DragSource.DataSource as GraphicObjectDesignContainer;
-                       if (godc == null)
-                               return;
-                       createDraggedObj (godc.CrowType);
-               }
-               protected override void onDragLeave (object sender, DragDropEventArgs e)
-               {
-                       base.onDragLeave (sender, e);
-
-                       ClearDraggedObj ();
-               }
-               #endregion
-
-               #region draggedObj handling
-               public GraphicObject draggedObj = null;
-               public GraphicObject draggedObjContainer = null;
-
-               bool tryAddDraggedObjTo(GraphicObject g){
-                       lock (imlVE.UpdateMutex) {
-                               if (g.GetType ().IsSubclassOf (typeof(Container))) {
-                                       Container c = g as Container;
-                                       c.SetChild (draggedObj);
-                                       EditorIsDirty = true;
-                               } else if (g.GetType ().IsSubclassOf (typeof(Group))) {
-                                       Group c = g as Group;
-                                       c.AddChild (draggedObj);
-                               } else
-                                       return false;
-                               EditorIsDirty = true;
-                               draggedObjContainer = g;
-                       }
-                       return true;
-               }
-               bool isPossibleContainer (GraphicObject g){
-                       if (g.GetType().IsSubclassOf(typeof(Container))){
-                               Container c = g as Container;
-                               return c.Child == null;
-                       }
-                       return g.GetType ().IsSubclassOf (typeof(Group));
-               }
-               void removeDraggedObjFrom(){
-                       if (draggedObjContainer == null)
-                               return;
-                       lock (imlVE.UpdateMutex) {
-                               if (draggedObjContainer.GetType().IsSubclassOf(typeof(Container))){
-                                       Container c = draggedObjContainer as Container;
-                                       c.SetChild (null);
-                                       EditorIsDirty = true;
-                                       //Console.WriteLine ("remove {0} from {1}", draggedObj, c);
-                               }else if (draggedObjContainer.GetType().IsSubclassOf(typeof(Group))){
-                                       Group c = draggedObjContainer as Group;
-                                       c.RemoveChild (draggedObj);
-                                       EditorIsDirty = true;
-                                       //Console.WriteLine ("remove {0} from {1}", draggedObj, c);
-                               }//else
-                               //      Console.WriteLine ("Error removing dragged obj");
-                       }
-                       draggedObjContainer = null;
-               }
-               void createDraggedObj (Type crowType) {
-                       lock (imlVE.UpdateMutex) {
-                               draggedObj = imlVE.CreateITorFromIMLFragment ("<" + crowType.Name + "/>").CreateInstance ();
-                       }
-               }
-               public void ClearDraggedObj (bool removeFromTree = true) {
-                       //Console.WriteLine ("Clear dragged obj {0}, remove from tree = {1}", draggedObj, removeFromTree);
-                       if (removeFromTree)
-                               removeDraggedObjFrom ();
-                       draggedObjContainer = null;
-                       if (draggedObj == null)
-                               return;
-                       if (removeFromTree)
-                               draggedObj.Dispose ();
-                       draggedObj = null;
-               }
-               #endregion
-
-
-               void WidgetCheckOver (GraphicObject go, MouseMoveEventArgs e){
-                       Type tGo = go.GetType();
-                       if (typeof(TemplatedGroup).IsAssignableFrom (tGo)) {
-                               
-                       } else if (typeof(TemplatedContainer).IsAssignableFrom (tGo)) {
-                               TemplatedContainer c = go as TemplatedContainer;
-                               if (c.Content?.MouseIsIn (e.Position) == true) {                                        
-                                       WidgetCheckOver (c.Content, e);
-                                       return;
-                               }
-                       } else if (typeof(TemplatedControl).IsAssignableFrom (tGo)) {
-                       } else if (typeof(Group).IsAssignableFrom (tGo)) {
-                               Group c = go as Group;
-                               for (int i = c.Children.Count -1; i >= 0; i--) {
-                                       if (c.Children[i].MouseIsIn (e.Position)) {                                     
-                                               WidgetCheckOver (c.Children[i], e);
-                                               return;
-                                       }
-                               }
-                       } else if (typeof(Crow.Container).IsAssignableFrom (tGo)) {
-                               Crow.Container c = go as Crow.Container;
-                               if (c.Child?.MouseIsIn (e.Position)==true) {                                    
-                                       WidgetCheckOver (c.Child, e);
-                                       return;
-                               }
-                       }
-                       HoverWidget = go;
-                       WidgetMouseEnter (go, e);
-               }
-               void WidgetMouseLeave (GraphicObject go, MouseMoveEventArgs e){
-
-               }
-               void WidgetMouseEnter (GraphicObject go, MouseMoveEventArgs e){
-
-               }
-               void WidgetMouseMove (GraphicObject go, MouseMoveEventArgs e){}
-               public bool ProcessMouseMove(int x, int y)
-               {
-                       int deltaX = x - imlVE.Mouse.X;
-                       int deltaY = y - imlVE.Mouse.Y;
-                       imlVE.Mouse.X = x;
-                       imlVE.Mouse.Y = y;
-                       MouseMoveEventArgs e = new MouseMoveEventArgs (x, y, deltaX, deltaY);
-                       e.Mouse = imlVE.Mouse;
-
-                       if (imlVE.ActiveWidget != null) {
-                               //TODO, ensure object is still in the graphic tree
-                               //send move evt even if mouse move outside bounds
-                               WidgetMouseMove (imlVE.ActiveWidget, e);
-                               return true;
-                       }
-
-                       if (HoverWidget != null) {
-                               //TODO, ensure object is still in the graphic tree
-                               //check topmost graphicobject first
-                               GraphicObject tmp = HoverWidget;
-                               GraphicObject topc = null;
-                               while (tmp is GraphicObject) {
-                                       topc = tmp;
-                                       tmp = tmp.LogicalParent as GraphicObject;
-                               }
-                               int idxhw = imlVE.GraphicTree.IndexOf (topc);
-                               if (idxhw != 0) {
-                                       int i = 0;
-                                       while (i < idxhw) {
-                                               if (imlVE.GraphicTree [i].LogicalParent == imlVE.GraphicTree [i].Parent) {
-                                                       if (imlVE.GraphicTree [i].MouseIsIn (e.Position)) {
-                                                               while (imlVE.HoverWidget != null) {
-                                                                       WidgetMouseLeave (imlVE.HoverWidget, e);
-                                                                       imlVE.HoverWidget = imlVE.HoverWidget.LogicalParent as GraphicObject;
-                                                               }
-
-                                                               WidgetCheckOver (GraphicTree [i], e);
-                                                               return true;
-                                                       }
-                                               }
-                                               i++;
-                                       }
-                               }
-
-
-                               if (imlVE.HoverWidget.MouseIsIn (e.Position)) {
-                                       WidgetCheckOver (imlVE.HoverWidget, (e));
-                                       return true;
-                               } else {
-                                       WidgetMouseLeave (imlVE.HoverWidget, e);
-                                       //seek upward from last focused graph obj's
-                                       while (imlVE.HoverWidget.LogicalParent as GraphicObject != null) {
-                                               imlVE.HoverWidget = imlVE.HoverWidget.LogicalParent as GraphicObject;
-                                               if (imlVE.HoverWidget.MouseIsIn (e.Position)) {
-                                                       WidgetCheckOver (imlVE.HoverWidget, e);
-                                                       return true;
-                                               } else
-                                                       WidgetMouseLeave (imlVE.HoverWidget, e);
-                                       }
-                               }
-                       }
-
-                       //top level graphic obj's parsing
-                       lock (imlVE.GraphicTree) {
-                               for (int i = 0; i < imlVE.GraphicTree.Count; i++) {
-                                       GraphicObject g = imlVE.GraphicTree [i];
-                                       if (g.MouseIsIn (e.Position)) {
-                                               WidgetCheckOver (g, e);
-                                               return true;
-                                       }
-                               }
-                       }
-                       imlVE.HoverWidget = null;
-                       return false;
-
-               }
-
-               void GTView_SelectedItemChanged (object sender, SelectionChangeEventArgs e)
-               {
-                       SelectedItem = e.NewValue as GraphicObject;
-               }
-       }
-}
index f96ec5cd1fb78cd2daad4e55da2ba35a3550fbc5..1c4c8b26a431dd1128967d328ec13857791cc075 100644 (file)
@@ -200,15 +200,15 @@ namespace Crow.Coding
                        : base (pi.Project, pi.node) {
 
                        cmdSave = new Crow.Command (new Action (() => Save ()))
-                       { Caption = "Save", Icon = new SvgPicture ("#Crow.Coding.ui.icons.inbox.svg"), CanExecute = false };
-                       cmdSave = new Crow.Command (new Action (() => SaveAs ()))
-                       { Caption = "Save As ..", Icon = new SvgPicture ("#Crow.Coding.ui.icons.inbox.svg"), CanExecute = false };
+                               { Caption = "Save", Icon = new SvgPicture ("#Crow.Coding.ui.icons.inbox.svg"), CanExecute = false };
+                       cmdSaveAs = new Crow.Command (new Action (() => SaveAs ()))
+                               { Caption = "Save As ..", Icon = new SvgPicture ("#Crow.Coding.ui.icons.inbox.svg"), CanExecute = false };
                        cmdOpen = new Crow.Command (new Action (() => Open ())) 
                                { Caption = "Open", Icon = new SvgPicture ("#Crow.Coding.ui.icons.outbox.svg"), CanExecute = false };
                        cmdUndo = new Crow.Command (new Action (() => Undo (null))) 
-                       { Caption = "Undo", Icon = new SvgPicture ("#Crow.Coding.icons.undo.svg"), CanExecute = false };
+                               { Caption = "Undo", Icon = new SvgPicture ("#Crow.Coding.icons.undo.svg"), CanExecute = false };
                        cmdRedo = new Crow.Command (new Action (() => Redo (null))) 
-                       { Caption = "Redo", Icon = new SvgPicture ("#Crow.Coding.icons.redo.svg"), CanExecute = false };
+                               { Caption = "Redo", Icon = new SvgPicture ("#Crow.Coding.icons.redo.svg"), CanExecute = false };
                                
                        Commands.Insert (0, cmdOpen);
                        Commands.Insert (1, cmdSave);
@@ -453,6 +453,14 @@ namespace Crow.Coding
                                NotifyValueChanged ("Instance", instance);
                        }
                }
+
+               public List<GraphicObject> GraphicTree { 
+                       get { return new List<GraphicObject> (new GraphicObject[] {instance}); }
+               }
+
+               void GTView_SelectedItemChanged (object sender, SelectionChangeEventArgs e){
+                       SelectedItem = e.NewValue;
+               }
        }
 }
 
index fb4bcbfab57dacfd7847ae362bf098928827349b..1b89dc09618e84abf0cb3567655e1195b1b4c597 100644 (file)
@@ -214,6 +214,15 @@ namespace Crow.Coding{
                        saveOpenedItemsInUserConfig ();
                }
 
+               public void CloseSolution () {
+                       while (openedItems.Count > 0) {
+                               openedItems.RemoveElement (openedItems [0]);
+                       }
+                       while (toolboxItems.Count > 0) {
+                               toolboxItems.RemoveElement (toolboxItems [0]);
+                       }
+                       NotifyValueChanged ("Projects", null);
+               }
            /// <summary>
            /// Solution name
            /// </summary>
diff --git a/CrowIDE/src/SourceEditor/BufferParser.cs b/CrowIDE/src/SourceEditor/BufferParser.cs
deleted file mode 100644 (file)
index dfec17a..0000000
+++ /dev/null
@@ -1,380 +0,0 @@
-using System;
-using System.IO;
-using Crow;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Text;
-
-namespace Crow.Coding
-{
-       /// <summary>
-       /// base class for tokenizing sources
-       /// </summary>
-       public abstract class BufferParser
-       {
-               /// <summary>
-               /// Default tokens, this enum may be overriden in derived parser with the new keyword,
-               /// see XMLParser for example.
-               /// </summary>
-               public enum TokenType {
-                       Unknown = 0,
-                       WhiteSpace = 1,
-                       NewLine = 2,
-                       LineComment = 3,
-                       BlockCommentStart = 4,
-                       BlockComment = 5,
-                       BlockCommentEnd = 6,
-                       Preprocessor = 7,
-                       Identifier = 8,
-                       Keyword = 9,
-                       OpenBlock = 10,
-                       CloseBlock = 11,
-                       StatementEnding = 12,
-                       OperatorOrPunctuation = 13,
-                       IntegerLitteral = 14,
-                       RealLitteral = 15,
-                       StringLitteralOpening = 16,
-                       StringLitteralClosing = 17,
-                       StringLitteral = 18,
-                       CharLitteralOpening = 19,
-                       CharLitteralClosing = 20,
-                       CharLitteral = 21,
-                       BoolLitteral = 22,
-                       NullLitteral = 23,                       
-                       Type = 24,
-               }
-
-               #region CTOR
-               public BufferParser (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
-
-               internal int currentLine = 0;
-               internal int currentColumn = 0;
-
-               int syntTreeDepth = 0;
-               public int SyntacticTreeDepth {
-                       get { return syntTreeDepth;}
-                       set {
-                               syntTreeDepth = value;
-                               if (syntTreeDepth > SyntacticTreeMaxDepth)
-                                       SyntacticTreeMaxDepth = syntTreeDepth;
-                       }
-               }
-               public int SyntacticTreeMaxDepth = 0;
-
-               protected CodeBuffer buffer;
-               protected Token currentTok;
-               protected bool eol = true;
-               protected Point CurrentPosition {
-                       get { return new Point (currentLine, currentColumn); }
-                       set {
-                               currentLine = value.Y;
-                               currentColumn = value.X;
-                       }
-               }
-
-               public Node RootNode;
-
-               public abstract void ParseCurrentLine();
-               public abstract void SyntaxAnalysis ();
-               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 ParserException)
-                                       SetLineInError (ex as ParserException);
-                       }
-               }
-               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 ParserException)
-                                       SetLineInError (ex as ParserException);
-                       }
-
-               }
-
-               public virtual void SetLineInError(ParserException 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);
-               }
-               public virtual string LineBrkRegex {
-                       get { return @"\r\n|\r|\n|\\\\n"; }
-               }
-               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 ParserException(parser, "closing tag not corresponding"));
-                       //                                      }
-                       //
-                       //                              }
-                       //                      }
-               }
-
-               #region low level parsing
-               protected void addCharToCurTok(char c, Point position){
-                       currentTok.Start = position;
-                       currentTok += c;
-               }
-               /// <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 ();
-               }
-               protected void setPreviousTokOfTypeTo (TokenType inType, TokenType newType) {
-                       for (int i = currentLine; i >= 0; i--) {
-                               int j = buffer [i].Tokens.Count - 1;
-                               while (j >= 0) {
-                                       if (buffer [i].Tokens [j].Type == inType) {
-                                               Token t = buffer [i].Tokens [j];
-                                               t.Type = newType;
-                                               buffer [i].Tokens [j] = t;
-                                               return;
-                                       }
-                                       j--;
-                               }                               
-                       }
-               }
-               /// <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 ParserException (currentLine, currentColumn, "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 ParserException (currentLine, currentColumn, "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;
-               }
-               protected virtual string Read(int charCount){
-                       string tmp = "";
-                       for (int i = 0; i < charCount; i++) {
-                               if (eol)
-                                       break;
-                               tmp += Read ();
-                       }
-                       return tmp;
-               }
-               /// <summary>
-               /// read until end of line is reached
-               /// </summary>
-               /// <returns>string read</returns>
-               protected virtual string ReadLine () {
-                       StringBuilder tmp = new StringBuilder();
-                       char c = Read ();
-                       while (!eol) {
-                               tmp.Append (c);
-                               c = Read ();
-                       }
-                       return tmp.ToString();
-               }
-               /// <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 ParserException (currentLine, currentColumn, "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
-
-               protected Node addChildNode (Node curNode, CodeLine cl, int tokPtr, string type = "") {
-                       Node n = new Node () { Name = cl.Tokens [tokPtr].Content, StartLine = cl, Type = type };
-                       curNode.AddChild (n);
-                       if (cl.SyntacticNode == null)
-                               cl.SyntacticNode = n;
-                       SyntacticTreeDepth++;
-                       return n;
-               }
-               protected void closeNodeAndGoUp (ref Node n, CodeLine cl, string type = ""){
-                       while (n != null) {
-                               if (n.Type == type) {
-                                       n.EndLine = cl;
-                                       n = n.Parent;
-                                       SyntacticTreeDepth--;
-                                       break;
-                               }
-                               n = n.Parent;
-                               SyntacticTreeDepth--;
-                       }
-               }
-               protected void closeNodeAndGoUp (ref Node n, CodeLine cl){
-                       SyntacticTreeDepth--;
-                       n.EndLine = cl;
-                       n = n.Parent;
-               }
-
-               protected void initSyntaxAnalysis () {
-                       RootNode = new Node () { Name = "RootNode", Type="Root" };
-                       SyntacticTreeDepth = SyntacticTreeMaxDepth = 0;
-               }
-
-
-               protected void throwParserException(string msg){
-                       throw new ParserException (currentLine, currentColumn, msg);
-               }
-       }
-}
\ No newline at end of file
diff --git a/CrowIDE/src/SourceEditor/CSharpParser.cs b/CrowIDE/src/SourceEditor/CSharpParser.cs
deleted file mode 100644 (file)
index 62090bc..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-using System;
-using Crow;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Text.RegularExpressions;
-using System.Linq;
-
-namespace Crow.Coding
-{
-       public class CSharpParser : BufferParser
-       {
-               #region keywords
-               string[] keywords = new string[] {
-                       "abstract",
-                       "as",
-                       "ascending",
-                       "async",
-                       "await",
-                       "base",
-                       "bool",
-                       "break",
-                       "byte",
-                       "case",
-                       "catch",
-                       "char",
-                       "checked",
-                       "class",
-                       "const",
-                       "continue",
-                       "decimal",
-                       "default",
-                       "delegate",
-                       "descending",
-                       "do",
-                       "double",
-                       "dynamic",
-                       "else",
-                       "enum",
-                       "equals",
-                       "event",
-                       "explicit",
-                       "extern",
-                       "false",
-                       "finally",
-                       "fixed",
-                       "float",
-                       "for",
-                       "foreach",
-                       "from",
-                       "get",
-                       "goto",
-                       "group",
-                       "if",
-                       "implicit",
-                       "in",
-                       "int",
-                       "interface",
-                       "internal",
-                       "is",
-                       "join",
-                       "let",
-                       "lock",
-                       "long",
-                       "nameof",
-                       "namespace",
-                       "new",
-                       "null",
-                       "object",
-                       "operator",
-                       "orderby",
-                       "out",
-                       "override",
-                       "params",
-                       "partial",
-                       "private",
-                       "protected",
-                       "public",
-                       "readonly",
-                       "ref",
-                       "return",
-                       "sbyte",
-                       "sealed",
-                       "select",
-                       "set",
-                       "short",
-                       "sizeof",
-                       "stackalloc",
-                       "static",
-                       "string",
-                       "struct",
-                       "switch",
-                       "this",
-                       "throw",
-                       "true",
-                       "try",
-                       "typeof",
-                       "uint",
-                       "ulong",
-                       "unchecked",
-                       "unsafe",
-                       "ushort",
-                       "using",
-                       "value",
-                       "var",
-                       "virtual",
-                       "void",
-                       "volatile",
-                       "when",
-                       "where",
-                       "while",
-                       "yield "                        
-               };
-               #endregion
-
-               public enum States
-               {
-                       init,       
-                       BlockComment,
-                       InNameSpace,
-                       InClass,
-                       InMember,
-                       Unknown,
-               }
-
-               public CSharpParser (CodeBuffer _buffer) : base(_buffer)
-               {
-               }
-
-               #region Regular Expression for validity checks
-               static Regex rxValidChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}");
-               static Regex rxNameStartChar = new Regex(@"_|\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}");
-               static Regex rxNameChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}");
-               static Regex rxNewLineChar = new Regex(@"\u000D|\u000A|\u0085|\u2028|\u2029");
-               static Regex rxWhiteSpaceChar = new Regex(@"\p{Zs}|\u0009|\u000B|\u000C");
-               static Regex rxDecimal = new Regex(@"[0-9]+");
-               static Regex rxHexadecimal = new Regex(@"[0-9a-fA-F]+");
-
-               public static bool CharIsValidCharStartName (char c) {
-                       return rxNameStartChar.IsMatch(new string(new char[]{c}));
-               }
-               public static bool CharIsValidCharName (char c) {
-                       return rxNameChar.IsMatch(new string(new char[]{c}));
-               }
-
-               public bool nextCharIsValidCharStartName
-               {
-                       get { return CharIsValidCharStartName(Peek()); }
-               }
-               public bool nextCharIsValidCharName
-               {
-                       get { return CharIsValidCharName(Peek()); }
-               }
-               #endregion
-
-               States curState = States.init;
-               States savedState = 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) {
-                               if (currentTok.IsNull)
-                                       SkipWhiteSpaces ();
-
-                               if (curState == States.BlockComment) {
-                                       currentTok.Start = CurrentPosition;
-                                       currentTok.Type = (BufferParser.TokenType)TokenType.BlockComment;
-                                       currentTok += ReadLineUntil ("*/");
-                                       if (Peek (2) == "*/") {
-                                               readToCurrTok (2);
-                                               curState = savedState;
-                                       }
-                                       saveAndResetCurrentTok ();
-                                       continue;
-                               }
-
-                               switch (Peek()) {
-                               case '\n':
-                                       eol = true;
-                                       if (!currentTok.IsNull)
-                                               saveAndResetCurrentTok ();
-                                       break;
-                               case '#':
-                                       readToCurrTok (true);
-                                       currentTok += ReadLine ();
-                                       saveAndResetCurrentTok (TokenType.Preprocessor);
-                                       break;
-                               case '/':
-                                       readToCurrTok (true);
-                                       switch (Peek ()) {
-                                       case '*':
-                                               readToCurrTok ();
-                                               currentTok += ReadLine ();
-                                               //currentTok.Type = (Parser.TokenType)TokenType.BlockComment;
-                                               savedState = curState;
-                                               curState = States.BlockComment;
-                                               saveAndResetCurrentTok (TokenType.BlockComment);
-                                               break;
-                                       case '/':
-                                               //readToCurrTok ();
-                                               currentTok += ReadLine ();
-                                               saveAndResetCurrentTok (TokenType.LineComment);
-                                               //currentTok.Type = (Parser.TokenType)TokenType.LineComment;
-                                               break;
-                                       default:
-                                               currentTok += ReadLine ();
-                                               saveAndResetCurrentTok (TokenType.Unknown);
-                                               break;
-                                       }
-                                       break;
-                               case '{':
-                                       if (currentTok.IsNull)
-                                               readAndResetCurrentTok (TokenType.OpenBlock, true);
-                                       else
-                                               readToCurrTok ();
-                                       break;
-                               case '}':
-                                       if (currentTok.IsNull)
-                                               readAndResetCurrentTok (TokenType.CloseBlock, true);
-                                       else
-                                               readToCurrTok ();                                       
-                                       break;
-                               case '\\'://unicode escape sequence
-                                       if (!(currentTok.Type == TokenType.Identifier ||
-                                           currentTok.IsEmpty || currentTok.Type == TokenType.StringLitteral || currentTok.Type == TokenType.CharLitteral)) {
-                                               saveAndResetCurrentTok ();
-                                       }
-                                       Point pos = CurrentPosition;
-                                       Read ();
-                                       char escChar = Read ();
-
-                                       if (escChar == 'u') {
-                                               char c = char.ConvertFromUtf32 (int.Parse (Read (4), System.Globalization.NumberStyles.HexNumber))[0];
-                                               if (currentTok.IsEmpty) {
-                                                       if (!CharIsValidCharStartName (c))
-                                                               throwParserException ("expecting identifier start");                                                    
-                                                       currentTok.Start = pos;
-                                                       currentTok.Type = TokenType.Identifier;
-                                               } else if (currentTok.Type == TokenType.Identifier) {
-                                                       if (!CharIsValidCharName (c))
-                                                               throwParserException ("expecting identifier valid char");                                               
-                                               }
-                                               currentTok += c;
-                                               break;
-                                       }
-                                       currentTok += new String (new char[] { '\\', escChar });
-                                       break;
-                               case '\'':
-                                       if (currentTok.IsNull) {
-                                               readAndResetCurrentTok (TokenType.CharLitteralOpening, true);
-                                               currentTok.Type = TokenType.CharLitteral;
-                                       } else if (currentTok.Type == TokenType.CharLitteral) {
-                                               saveAndResetCurrentTok ();
-                                               readAndResetCurrentTok (TokenType.CharLitteralClosing, true);
-                                       } else if (currentTok.Type == TokenType.StringLitteral){
-                                               readToCurrTok ();
-                                       } else
-                                               throwParserException ("unexpected character: (\')");                                            
-                                       break;
-                               case '"':
-                                       if (currentTok.IsNull) {
-                                               readAndResetCurrentTok (TokenType.StringLitteralOpening, true);
-                                               currentTok.Type = TokenType.StringLitteral;
-                                       } else if (currentTok.Type == TokenType.StringLitteral) {
-                                               saveAndResetCurrentTok ();
-                                               readAndResetCurrentTok (TokenType.StringLitteralClosing, true);
-                                       } else
-                                               throwParserException ("unexpected character: (\")");
-                                       break;
-                               default:
-                                       if (currentTok.Type == TokenType.StringLitteral || currentTok.Type == TokenType.CharLitteral) {
-                                               readToCurrTok (currentTok.IsEmpty);
-                                       } else if (currentTok.IsNull) {
-                                               if (nextCharIsValidCharStartName) {                                             
-                                                       readToCurrTok (true);
-                                                       while (nextCharIsValidCharName)
-                                                               readToCurrTok ();
-
-                                                       if (keywords.Contains (currentTok.Content))
-                                                               saveAndResetCurrentTok (TokenType.Keyword);
-                                                       else
-                                                               saveAndResetCurrentTok (TokenType.Identifier);
-                                                       continue;
-                                               } else
-                                                       readAndResetCurrentTok(TokenType.Unknown, true);
-                                       } else
-                                               readAndResetCurrentTok(TokenType.Unknown, true);                                        
-                                       break;
-                               }
-                       }
-
-                       if (cl.EndingState != (int)curState && currentLine < buffer.LineCount - 1)
-                               buffer [currentLine + 1].Tokens = null;
-
-                       cl.EndingState = (int)curState;
-               }
-               
-               public override void SyntaxAnalysis ()
-               {
-                       initSyntaxAnalysis ();
-                       Node currentNode = RootNode;
-
-                       int ptrLine = 0;
-                       while (ptrLine < buffer.LineCount) {
-                               CodeLine cl = buffer [ptrLine];
-                               if (cl.Tokens == null){
-                                       ptrLine++;
-                                       continue;
-                               }
-                               cl.SyntacticNode = null;
-
-                               int tokPtr = 0;
-                               bool onlyWhiteSpace = true;
-                               while (tokPtr < cl.Tokens.Count) {
-                                       if (cl.Tokens [tokPtr].Type == TokenType.WhiteSpace) {
-                                               tokPtr++;
-                                               continue;
-                                       }
-
-                                       if (cl.Tokens [tokPtr].Type == TokenType.LineComment && onlyWhiteSpace) {
-                                               int startLine = ptrLine;
-                                               ptrLine++;
-                                               while (ptrLine < buffer.LineCount) {
-                                                       int idx = buffer [ptrLine].FirstNonBlankTokIndex;
-                                                       if (idx < 0) 
-                                                               break;
-                                                       if (buffer [ptrLine].Tokens [idx].Type != TokenType.LineComment)
-                                                               break;
-                                                       ptrLine++;
-                                               }
-                                               ptrLine--;
-                                               if (ptrLine - startLine > 0) {
-                                                       currentNode = addChildNode (currentNode, cl, tokPtr, "comment");
-                                                       closeNodeAndGoUp (ref currentNode, buffer [ptrLine], "comment");
-                                               }
-                                               break;
-                                       }
-
-                                       switch (cl.Tokens [tokPtr].Type) {
-                                       case TokenType.OpenBlock:
-                                               currentNode = addChildNode (currentNode, cl, tokPtr);
-                                               break;
-                                       case TokenType.CloseBlock:                                              
-                                               closeNodeAndGoUp (ref currentNode, cl);
-                                               break;
-                                       case TokenType.Preprocessor:
-                                               if (cl.Tokens [tokPtr].Content.StartsWith ("#region")) {
-                                                       currentNode = addChildNode (currentNode, cl, tokPtr, "region");
-                                               } else if (cl.Tokens [tokPtr].Content.StartsWith ("#endregion")) {
-                                                       
-                                                       closeNodeAndGoUp (ref currentNode, cl,"region");
-                                               }
-                                               break;
-                                       }
-                                       onlyWhiteSpace = false;
-                                       tokPtr++;
-                               }
-                               ptrLine++;
-                       }
-                       ptrLine = 0;
-                       while (ptrLine < buffer.LineCount) {
-                               CodeLine cl = buffer [ptrLine];
-                               if (cl.IsFoldable) {
-                                       if (cl.SyntacticNode.Type == "comment" || cl.SyntacticNode.Type == "region")
-                                               cl.IsFolded = true;
-                               }
-                               ptrLine++;
-                       }
-               }
-       }
-}
-
diff --git a/CrowIDE/src/SourceEditor/CodeBuffer.cs b/CrowIDE/src/SourceEditor/CodeBuffer.cs
deleted file mode 100644 (file)
index 13c422a..0000000
+++ /dev/null
@@ -1,528 +0,0 @@
-//
-//  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;
-using System.Threading;
-
-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 ReaderWriterLockSlim editMutex = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
-
-               //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
-
-               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;
-                               editMutex.EnterWriteLock ();
-                               lines [i] = value;
-                               editMutex.ExitWriteLock ();
-                               LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
-                       }
-               }
-
-               public void RemoveAt(int i){
-                       editMutex.EnterWriteLock ();
-                       lines.RemoveAt (i);
-                       editMutex.ExitWriteLock ();
-                       LineRemoveEvent.Raise (this, new CodeBufferEventArgs (i));
-               }
-               public void Insert(int i, string item){
-                       editMutex.EnterWriteLock ();
-                       lines.Insert (i, item);
-                       editMutex.ExitWriteLock ();
-                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (i));
-               }
-               public void Add(CodeLine item){
-                       editMutex.EnterWriteLock ();
-                       lines.Add (item);
-                       editMutex.ExitWriteLock ();
-                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (lines.Count - 1));
-               }
-               public void AddRange (string[] items){
-                       int start = lines.Count;
-                       editMutex.EnterWriteLock ();
-                       for (int i = 0; i < items.Length; i++)
-                               lines.Add (items [i]);
-                       editMutex.ExitWriteLock ();
-                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length));
-               }
-               public void AddRange (CodeLine[] items){
-                       int start = lines.Count;
-                       editMutex.EnterWriteLock ();
-                       lines.AddRange (items);
-                       editMutex.ExitWriteLock ();
-                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length));
-               }
-               public void Clear () {
-                       editMutex.EnterWriteLock ();
-                       longestLineCharCount = 0;
-                       lines.Clear ();
-                       editMutex.ExitWriteLock ();
-                       BufferCleared.Raise (this, null);
-               }
-               public void UpdateLine(int i, string newContent){
-                       editMutex.EnterWriteLock ();
-                       this [i].Content = newContent;
-                       editMutex.ExitWriteLock ();
-                       LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
-               }
-               public void AppenedLine(int i, string newContent){
-                       editMutex.EnterWriteLock ();
-                       this [i].Content += newContent;
-                       editMutex.ExitWriteLock ();
-                       LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
-               }
-               public void RemoveLeadingTab (int l) {
-                       if (this [l] [0] == '\t') {
-                               UpdateLine (l, this [l].Content.Substring (1));
-                               return;
-                       }
-                       int i = 0;
-                       while (i < Interface.TabSize) {
-                               if (this [l] [i] != ' ')
-                                       break;
-                               i++;
-                       }
-                       if (i > 0)
-                               UpdateLine (l, this [l].Content.Substring (i));
-               }
-               public void ToogleFolding (int line) {
-                       if (!this [line].IsFoldable)
-                               return;
-                       editMutex.EnterWriteLock ();
-                       this [line].IsFolded = !this [line].IsFolded;
-                       editMutex.ExitWriteLock ();
-                       FoldingEvent.Raise (this, new CodeBufferEventArgs (line));
-               }
-               public void Load(string rawSource, string lineBrkRegex = @"\r\n|\r|\n|\\\n") {
-                       this.Clear();
-
-                       if (string.IsNullOrEmpty (rawSource))
-                               return;
-
-                       AddRange (Regex.Split (rawSource, lineBrkRegex));
-
-                       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;
-                       editMutex.EnterReadLock ();
-                       for (int i = 0; i < this.LineCount; i++) {
-                               if (lines[i].PrintableLength > longestLineCharCount) {
-                                       longestLineCharCount = lines[i].PrintableLength;
-                                       longestLineIdx = i;
-                               }
-                       }
-                       editMutex.ExitReadLock ();
-                       //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 = "";
-                               editMutex.EnterReadLock ();
-                               for (int i = 0; i < lines.Count -1; i++)
-                                       tmp += lines [i].Content + this.lineBreak;
-                               tmp += lines [lines.Count - 1].Content;
-                               editMutex.ExitReadLock ();
-                               return tmp;
-                       }
-               }
-
-               /// <summary>
-               /// unfolded and not in folds line count
-               /// </summary>
-               public int UnfoldedLines {
-                       get {
-                               int i = 0, vl = 0;
-                               editMutex.EnterReadLock ();
-                               while (i < LineCount) {
-                                       if (this [i].IsFolded) {
-                                               i = GetEndNodeIndex (i);
-                                               if (i < 0) {
-                                                       Console.WriteLine ("error folding");
-                                                       break;
-                                               }
-                                       }
-                                       i++;
-                                       vl++;
-                               }
-                               editMutex.ExitReadLock ();
-                               //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);
-               }
-
-               int ConverteTabulatedPosOfCurLine (int column) {
-                       int tmp = 0;
-                       int i = 0;
-                       while (i < lines [_currentLine].Content.Length){
-                               if (lines [_currentLine].Content [i] == '\t')
-                                       tmp += 4;
-                               else
-                                       tmp++;
-                               if (tmp > column)
-                                       break;
-                               i++;
-                       }
-                       return i;
-               }
-
-               public int CurrentTabulatedColumn {
-                       get {
-                               return lines [_currentLine].Content.Substring (0, _currentCol).
-                                       Replace ("\t", new String (' ', Interface.TabSize)).Length;
-                       }
-               }
-               /// <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);
-               }
-               public void SetSelectionOnFullLines () {
-                       if (!SelectionInProgress)
-                               return;
-                       Point s = new Point (0, SelectionStart.Y);
-                       Point e = new Point (this [SelectionEnd.Y].Length, SelectionEnd.Y);
-                       selStartPos = s;
-                       selEndPos = e;
-                       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; } }
-               int requestedColumn = -1;
-               /// <summary>
-               /// Current column in buffer coordinate, tabulation = 1 char
-               /// </summary>
-               public int CurrentColumn{
-                       get { return _currentCol; }
-                       set {
-                               if (value == _currentCol)
-                                       return;
-
-                               editMutex.EnterReadLock ();
-
-                               if (value < 0)
-                                       _currentCol = 0;
-                               else if (value > lines [_currentLine].Length)
-                                       _currentCol = lines [_currentLine].Length;
-                               else
-                                       _currentCol = value;
-
-                               requestedColumn = CurrentTabulatedColumn;
-
-                               editMutex.ExitReadLock ();
-
-                               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;
-
-                               editMutex.EnterReadLock ();
-
-                               if (value >= lines.Count)
-                                       _currentLine = lines.Count-1;
-                               else if (value < 0)
-                                       _currentLine = 0;
-                               else
-                                       _currentLine = value;
-//                             if (_currentCol < 0)
-//                                     requestedColumn = tabu _currentCol;
-                               int tabulatedRequestedCol = ConverteTabulatedPosOfCurLine(requestedColumn);
-                               if (requestedColumn > lines [_currentLine].PrintableLength)
-                                       _currentCol = lines [_currentLine].Length;
-                               else
-                                       //_currentCol = requestedColumn;
-                                       _currentCol = tabulatedRequestedCol;
-                               //Debug.WriteLine ("buff cur line: " + _currentLine);
-
-                               editMutex.ExitReadLock();
-
-                               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()
-               {
-                       editMutex.EnterWriteLock ();
-                       if (SelectionIsEmpty) {
-                               if (CurrentColumn == 0) {
-                                       if (CurrentLine == 0) {
-                                               editMutex.ExitWriteLock ();
-                                               return;
-                                       }
-                                       CurrentLine--;
-                                       CurrentColumn = this [CurrentLine].Length;
-                                       AppenedLine (CurrentLine, this [CurrentLine + 1].Content);
-                                       RemoveAt (CurrentLine + 1);
-                                       editMutex.ExitWriteLock ();
-                                       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 ();
-                       }
-                       editMutex.ExitWriteLock ();
-               }
-               /// <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
deleted file mode 100644 (file)
index 07dd25b..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-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
deleted file mode 100644 (file)
index 23f43fb..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-using System;
-using System.Text;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Crow.Coding
-{
-       public class CodeLine
-       {
-               public string Content;
-               public List<Token> Tokens;
-               public int EndingState = 0;
-               public Node SyntacticNode;
-               public ParserException 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 ? false :
-                               SyntacticNode.EndLine != SyntacticNode.StartLine && SyntacticNode.EndLine != null; } }
-               public int FoldingLevel { get { return IsFoldable ? SyntacticNode.Level : 0; } }
-               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 int FirstNonBlankTokIndex {
-                       get { return Tokens == null ? -1 : Tokens.FindIndex (tk=>tk.Type != BufferParser.TokenType.WhiteSpace); }
-               }
-
-               public void SetLineInError (ParserException 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
deleted file mode 100644 (file)
index 9db5542..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-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 int Level {
-                       get { return Parent == null ? 1 : Parent.Level + 1; } 
-               }
-
-               public override string ToString ()
-               {
-                       return string.Format ("Name:{0}, Type:{1}\n\tparent:{2}", Name, Type, Parent);
-               }
-       }
-}
-
diff --git a/CrowIDE/src/SourceEditor/SourceEditor.cs b/CrowIDE/src/SourceEditor/SourceEditor.cs
deleted file mode 100644 (file)
index 1453813..0000000
+++ /dev/null
@@ -1,1205 +0,0 @@
-//
-// 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 : Editor
-       {               
-               #region CTOR
-               public SourceEditor (): base()
-               {
-                       formatting.Add ((int)XMLParser.TokenType.AttributeName, new TextFormatting (Color.Teal, 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.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.TractorRed, Color.Transparent, false, true));
-                       formatting.Add ((int)XMLParser.TokenType.XMLDecl, new TextFormatting (Color.AoEnglish, Color.Transparent));
-
-                       formatting.Add ((int)BufferParser.TokenType.BlockComment, new TextFormatting (Color.Gray, Color.Transparent, false, true));
-                       formatting.Add ((int)BufferParser.TokenType.LineComment, new TextFormatting (Color.Gray, Color.Transparent, false, true));
-                       formatting.Add ((int)BufferParser.TokenType.OperatorOrPunctuation, new TextFormatting (Color.Black, Color.Transparent));
-                       //formatting.Add ((int)BufferParser.TokenType.Keyword, new TextFormatting (Color.DarkCyan, Color.Transparent));
-
-                       parsing.Add (".crow", "Crow.Coding.XMLParser");
-                       parsing.Add (".svg", "Crow.Coding.XMLParser");
-                       parsing.Add (".template", "Crow.Coding.XMLParser");
-                       parsing.Add (".cs", "Crow.Coding.CSharpParser");
-                       parsing.Add (".style", "Crow.Coding.StyleParser");
-
-                       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(""));
-               }
-               #endregion
-
-               string oldSource = "";
-               //save requested position on error, and try it on next move
-               int requestedLine = 0, requestedCol = 0;
-               volatile bool isDirty = false;
-
-               const int leftMarginGap = 3;//gap between items in margin and text
-               const int foldSize = 9;//folding rectangles size
-               const int foldHSpace = 4;//folding level tabulation x
-               int foldMargin { get { return parser == null ? 0 : parser.SyntacticTreeMaxDepth * foldHSpace; }}//folding margin size
-
-               #region private and protected fields
-               bool foldingEnabled = true;
-               int leftMargin = 0;     //margin used to display line numbers, folding errors,etc...
-               int visibleLines = 1;
-               int visibleColumns = 1;
-               int firstPrintedLine = -1;
-               int printedCurrentLine = 0;//Index of the currentline in the PrintedLines array
-
-               CodeBuffer buffer;
-               BufferParser parser;
-               List<CodeLine> PrintedLines;//list of lines visible in the Editor depending on scrolling and folding
-
-               Dictionary<int, TextFormatting> formatting = new Dictionary<int, TextFormatting>();
-               Dictionary<string, string> parsing = new Dictionary<string, string>();
-
-               Color selBackground;
-               Color selForeground;
-               int selStartCol;
-               int selEndCol;
-
-               protected Rectangle rText;
-               protected FontExtents fe;
-               protected TextExtents te;
-
-               Point mouseLocalPos;
-               bool doubleClicked = false;
-               #endregion
-
-               void measureLeftMargin () {
-                       leftMargin = 0;
-                       if (PrintLineNumbers)
-                               leftMargin += (int)Math.Ceiling((double)buffer.LineCount.ToString().Length * fe.MaxXAdvance) +6;
-                       if (foldingEnabled)
-                               leftMargin += foldMargin;
-                       if (leftMargin > 0)
-                               leftMargin += leftMarginGap;                    
-                       updateVisibleColumns ();
-               }
-               void findLongestLineAndUpdateMaxScrollX() {
-                       buffer.FindLongestVisualLine ();
-                       updateMaxScrollX ();
-//                     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.Ascent+fe.Descent));
-                       NotifyValueChanged ("VisibleLines", visibleLines);
-                       updateMaxScrollY ();
-                       updatePrintedLines ();
-                       RegisterForGraphicUpdate ();
-//                     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);
-                       NotifyValueChanged ("VisibleColumns", visibleColumns);
-                       updateMaxScrollX ();
-//                     System.Diagnostics.Debug.WriteLine ("update visible columns: {0} leftMargin:{1}",visibleColumns, leftMargin);
-//                     System.Diagnostics.Debug.WriteLine ("update MaxScrollX: " + MaxScrollX);
-               }
-               void updateMaxScrollX () {
-                       MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns);
-                       if (buffer.longestLineCharCount > 0)
-                               NotifyValueChanged ("ChildWidthRatio", Slot.Width * visibleColumns / buffer.longestLineCharCount);                      
-               }
-               void updateMaxScrollY () {
-                       if (parser == null || !foldingEnabled) {
-                               MaxScrollY = Math.Max (0, buffer.LineCount - visibleLines);
-                               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);                                                     
-                       }
-               }                       
-               void updatePrintedLines () {
-                       buffer.editMutex.EnterReadLock ();
-                       editorMutex.EnterWriteLock ();
-
-                       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++;
-                       }
-
-                       buffer.editMutex.ExitReadLock ();
-                       editorMutex.ExitWriteLock ();
-               }
-               void updateOnScreenCurLineFromBuffCurLine(){
-                       printedCurrentLine = PrintedLines.IndexOf (buffer.CurrentCodeLine);
-               }
-               void toogleFolding (int line) {
-                       if (parser == null || !foldingEnabled)
-                               return;
-                       buffer.ToogleFolding (line);
-               }
-
-               #region Editor overrides
-               protected override void updateEditorFromProjFile ()
-               {
-                       buffer.editMutex.EnterWriteLock ();
-                       loadSource ();
-                       buffer.editMutex.ExitWriteLock ();
-
-                       isDirty = false;
-                       oldSource = projFile.Source;
-                       CurrentLine = requestedLine;
-                       CurrentColumn = requestedCol;
-                       projFile.RegisteredEditors [this] = true;
-               }
-               protected override void updateProjFileFromEditor ()
-               {
-                       buffer.editMutex.EnterWriteLock ();
-                       string newsrc = buffer.FullText;
-                       buffer.editMutex.ExitWriteLock ();
-                       projFile.UpdateSource (this, newsrc);
-               }
-               protected override bool EditorIsDirty {
-                       get { return isDirty; }
-                       set { isDirty = value; }
-               }
-               protected override bool IsReady {
-                       get { return buffer != null; }
-               }
-               #endregion
-
-               #region Buffer events handlers
-               void Buffer_BufferCleared (object sender, EventArgs e)
-               {
-                       editorMutex.EnterWriteLock ();
-
-                       buffer.longestLineCharCount = 0;
-                       buffer.longestLineIdx = 0;
-                       measureLeftMargin ();
-                       MaxScrollX = MaxScrollY = 0;
-                       PrintedLines = null;
-                       RegisterForGraphicUpdate ();
-                       notifyPositionChanged ();
-                       isDirty = true;
-
-                       editorMutex.ExitWriteLock ();
-               }
-               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);
-                       }
-
-                       if (parser != null)
-                               parser.reparseSource ();
-
-                       measureLeftMargin ();
-
-                       updatePrintedLines ();
-                       updateMaxScrollY ();
-                       RegisterForGraphicUpdate ();
-                       notifyPositionChanged ();
-                       isDirty = true;
-               }
-               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 ();
-                       notifyPositionChanged ();
-                       isDirty = true;
-               }
-               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 ();
-                       notifyPositionChanged ();
-                       isDirty = true;
-               }
-               void Buffer_PositionChanged (object sender, EventArgs e)
-               {
-                       Console.WriteLine ("Position changes: ({0},{1})", buffer.CurrentLine, buffer.CurrentColumn);
-                       int cc = buffer.CurrentTabulatedColumn;
-
-                       if (cc > visibleColumns + ScrollX) {
-                               ScrollX = cc - visibleColumns;
-                       } else if (cc < ScrollX)
-                               ScrollX = cc;
-                       
-                       RegisterForGraphicUpdate ();
-                       updateOnScreenCurLineFromBuffCurLine ();
-                       notifyPositionChanged ();
-               }
-
-               void Buffer_SelectionChanged (object sender, EventArgs e)
-               {
-                       RegisterForGraphicUpdate ();
-               }
-               void Buffer_FoldingEvent (object sender, CodeBufferEventArgs e)
-               {
-                       updatePrintedLines ();
-                       updateOnScreenCurLineFromBuffCurLine ();
-                       updateMaxScrollY ();
-                       RegisterForGraphicUpdate ();
-               }
-               #endregion
-
-               void notifyPositionChanged (){
-                       try {                           
-                               NotifyValueChanged ("CurrentLine", buffer.CurrentLine+1);
-                               NotifyValueChanged ("CurrentColumn", buffer.CurrentColumn+1);
-                               NotifyValueChanged ("CurrentLineHasError", CurrentLineHasError);
-                               NotifyValueChanged ("CurrentLineError", CurrentLineError);
-                       } catch (Exception ex) {
-                               Console.WriteLine (ex.ToString ());
-                       }
-               }
-                       
-               #region Public Crow Properties
-               public int CurrentLine{
-                       get { return buffer == null ? 0 : buffer.CurrentLine+1; }
-                       set {
-                               try {
-                                       int l = value - 1;
-                                       if (l == buffer.CurrentLine)
-                                               return;
-                                       buffer.CurrentLine = l;
-                                       if (buffer [l].IsFolded)
-                                               buffer.ToogleFolding (l);                                       
-                               } catch (Exception ex) {
-                                       requestedLine = value - 1;
-                                       Console.WriteLine ("Error cur column: " + ex.ToString ());
-                               }
-                       }
-               }
-               public int CurrentColumn{
-                       get { return buffer == null ? 0 : buffer.CurrentColumn+1; }
-                       set {
-                               try {                                   
-                                       if (value - 1 == buffer.CurrentColumn)
-                                               return;
-                                       buffer.CurrentColumn = value - 1;
-                               } catch (Exception ex) {
-                                       requestedCol = value - 1;
-                                       Console.WriteLine ("Error cur column: " + ex.ToString ());
-                               }
-                       }
-               }
-               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 ();
-                       }
-               }
-               [DefaultValue("BlueGray")]
-               public virtual Color SelectionBackground {
-                       get { return selBackground; }
-                       set {
-                               if (value == selBackground)
-                                       return;
-                               selBackground = value;
-                               NotifyValueChanged ("SelectionBackground", selBackground);
-                               RegisterForRedraw ();
-                       }
-               }
-               [DefaultValue("White")]
-               public virtual Color SelectionForeground {
-                       get { return selForeground; }
-                       set {
-                               if (value == selForeground)
-                                       return;
-                               selForeground = value;
-                               NotifyValueChanged ("SelectionForeground", selForeground);
-                               RegisterForRedraw ();
-                       }
-               }
-               public override int ScrollY {
-                       get {
-                               return base.ScrollY;
-                       }
-                       set {
-                               if (value == base.ScrollY)
-                                       return;
-                               base.ScrollY = value;
-                               updatePrintedLines ();
-                               updateOnScreenCurLineFromBuffCurLine ();
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-               public ParserException CurrentLineError {
-                       get { return buffer?.CurrentCodeLine?.exception; }
-               }
-               public bool CurrentLineHasError {
-                       get { return buffer == null ? false : buffer.CurrentCodeLine == null ? false :
-                               buffer.CurrentCodeLine.exception != null; }
-               }
-               public override ProjectFile ProjectNode {
-                       get {
-                               return base.ProjectNode;
-                       }
-                       set {
-                               base.ProjectNode = value;
-                               if (projFile != null)
-                                       parser = getParserFromExt (System.IO.Path.GetExtension (projFile.Extension));
-                       }
-               }
-               #endregion
-
-               BufferParser 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 (BufferParser)Activator.CreateInstance (parserType, buffer );
-               }
-               void loadSource () {
-
-                       try {
-
-                               if (parser == null)
-                                       buffer.Load (projFile.Source);
-                               else//parser may have special linebrk rules
-                                       buffer.Load (projFile.Source, parser.LineBrkRegex);
-
-                       } catch (Exception ex) {
-                               Debug.WriteLine (ex.ToString ());
-                       }
-
-                       projFile.RegisteredEditors [this] = true;
-
-                       updateMaxScrollY ();
-                       MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns);
-                       updatePrintedLines ();
-
-                       RegisterForGraphicUpdate ();
-               }
-
-               /// <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.Ascent+fe.Descent) * 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.Ascent+fe.Descent)));
-                               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;
-                                       mgBg = Color.DarkGray;
-                               }
-                               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){
-
-                               Rectangle rFld = new Rectangle (cb.X + leftMargin - leftMarginGap - foldMargin,
-                                       (int)(y + (fe.Ascent + fe.Descent) / 2.0 - foldSize / 2.0), foldSize, foldSize);
-
-                               gr.SetSourceColor (Color.Black);
-                               gr.LineWidth = 1.0;
-
-                               int level = 0;
-                               bool closingNode = false;
-
-                               if (currentNode != null) {
-                                       if (cl == currentNode.EndLine) {
-                                               currentNode = currentNode.Parent;
-                                               closingNode = true;
-                                       }
-                                       if (currentNode != null)
-                                               level = currentNode.Level - 1;
-                               }
-
-                               for (int l = 0; l < level; l++) {                                       
-                                       gr.MoveTo (rFld.Center.X + 0.5, y);
-                                       gr.LineTo (rFld.Center.X + 0.5, y + fe.Ascent + fe.Descent);
-                                       rFld.Left += foldHSpace;
-                               }
-                               if (closingNode) {
-                                       gr.MoveTo (rFld.Center.X + 0.5, y);
-                                       gr.LineTo (rFld.Center.X + 0.5, y + fe.Ascent / 2 + 0.5);
-                                       gr.LineTo (rFld.Center.X + 0.5 + foldSize / 2, y + fe.Ascent / 2 + 0.5);
-                                       closingNode = false;
-                               }
-                               gr.SetDash (new double[]{ 1.5 },0.0);
-                               gr.SetSourceColor (Color.Gray);
-                               gr.Stroke ();
-                               gr.SetDash (new double[]{}, 0.0);
-
-                               if (cl.IsFoldable) {
-                                       gr.Rectangle (rFld);
-                                       gr.SetSourceColor (Color.White);
-                                       gr.Fill();
-                                       gr.SetSourceColor (Color.Black);
-                                       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);
-                                       }else
-                                               currentNode = cl.SyntacticNode;
-                                       
-                                       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);
-               }
-               Node currentNode = null;
-//             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.Ascent+fe.Descent));
-//                             gr.LineTo (0.5 + cursorX, cb.Y + (printedCurrentLine + 1) * (fe.Ascent+fe.Descent));
-//                             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.Ascent+fe.Descent));
-                               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.Ascent+fe.Descent));
-                                       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.Ascent+fe.Descent) * 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 ();
-               }
-
-               protected override void onDraw (Context gr)
-               {
-                       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);
-
-                       buffer.editMutex.EnterReadLock ();
-                       editorMutex.EnterReadLock ();
-
-                       #region draw text cursor
-                       if (buffer.SelectionInProgress){
-                               selStartCol = getTabulatedColumn (buffer.SelectionStart);
-                               selEndCol = getTabulatedColumn (buffer.SelectionEnd);
-                       }else if (HasFocus && printedCurrentLine >= 0){
-                               gr.LineWidth = 1.0;
-                               double cursorX = cb.X + (getTabulatedColumn(buffer.CurrentPosition) - ScrollX) * fe.MaxXAdvance + leftMargin;
-                               gr.MoveTo (0.5 + cursorX, cb.Y + (printedCurrentLine) * (fe.Ascent+fe.Descent));
-                               gr.LineTo (0.5 + cursorX, cb.Y + (printedCurrentLine + 1) * (fe.Ascent+fe.Descent));
-                               gr.Stroke();
-                       }
-                       #endregion
-
-                       if (PrintedLines != null) {                             
-                               int unfoldedLines = buffer.UnfoldedLines;
-                               currentNode = null;
-                               CodeLine cl = PrintedLines[0];
-                               int idx0 = buffer.IndexOf(cl);
-                               int li = idx0-1;
-                               while (li >= 0) {
-                                       if (buffer [li].IsFoldable && !buffer [li].IsFolded) {
-                                               if (buffer.IndexOf(buffer [li].SyntacticNode.EndLine) > idx0){
-                                                       currentNode = buffer [li].SyntacticNode;
-                                                       break;
-                                               }
-                                       }
-                                       li--;
-                               }
-
-                               for (int i = 0; i < visibleLines; i++) {
-                                       if (i + ScrollY >= unfoldedLines)//TODO:need optimize
-                                               break;
-                                       drawLine (gr, cb, i);
-                               }
-                       }
-
-                       editorMutex.ExitReadLock ();
-
-                       buffer.editMutex.ExitReadLock ();
-
-               }
-               #endregion
-
-               #region Mouse handling
-
-               int hoverLine = -1;
-               public int HoverLine {
-                       get { return hoverLine; }
-                       set { 
-                               if (hoverLine == value)
-                                       return;
-                               hoverLine = value;
-                               NotifyValueChanged ("HoverLine", hoverLine);                            
-                       }
-               }
-               void updateHoverLine () {
-                       int hvl = (int)Math.Max (0, Math.Floor (mouseLocalPos.Y / (fe.Ascent+fe.Descent)));
-                       hvl = Math.Min (PrintedLines.Count, hvl);
-                       HoverLine = buffer.IndexOf (PrintedLines[hvl]);
-               }
-               void updateCurrentPosFromMouseLocalPos(){                       
-                       PrintedCurrentLine = (int)Math.Max (0, Math.Floor (mouseLocalPos.Y / (fe.Ascent+fe.Descent)));
-                       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;
-               }
-               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;
-
-                       updateHoverLine ();
-
-                       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
-                       updateCurrentPosFromMouseLocalPos();
-                       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.Ascent+fe.Descent)))]));
-                               return;
-                       }
-
-                       updateCurrentPosFromMouseLocalPos ();
-                       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;
-
-                       if (e.Control) {
-                               switch (key) {
-                               case Key.S:
-                                       projFile.Save ();
-                                       break;
-                               case Key.W:
-                                       editorMutex.EnterWriteLock ();
-                                       if (e.Shift)
-                                               projFile.Redo (null);
-                                       else
-                                               projFile.Undo (null);
-                                       editorMutex.ExitWriteLock ();
-                                       break;
-                               default:
-                                       Console.WriteLine ("");
-                                       break;
-                               }
-                       }
-
-                       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:
-                               if (e.Shift) {
-                                       if (buffer.SelectionIsEmpty ||
-                                               (buffer.SelectionStart.Y == buffer.SelectionEnd.Y)) {
-                                               //TODO
-                                               break;
-                                       }
-                                       for (int i = buffer.SelectionStart.Y; i <= buffer.SelectionEnd.Y; i++)
-                                               buffer.RemoveLeadingTab (i);
-                                       buffer.SetSelectionOnFullLines ();
-                               } else {
-                                       if (buffer.SelectionIsEmpty ||
-                                               (buffer.SelectionStart.Y == buffer.SelectionEnd.Y)) {
-                                               buffer.Insert ("\t");
-                                               break;
-                                       }
-                                       for (int i = buffer.SelectionStart.Y; i <= buffer.SelectionEnd.Y; i++) {
-                                               buffer.UpdateLine (i, "\t" + buffer [i].Content);
-                                       }
-                               }
-
-                               break;
-                       case Key.F8:
-                               toogleFolding (buffer.CurrentLine);
-                               break;
-                       default:
-                               break;
-                       }
-                       RegisterForGraphicUpdate();
-               }
-               public override void onKeyPress (object sender, KeyPressEventArgs e)
-               {
-                       base.onKeyPress (sender, e);
-
-                       buffer.Insert (e.KeyChar.ToString());
-                       buffer.ResetSelection ();
-               }
-               #endregion
-       }
-}
\ No newline at end of file
diff --git a/CrowIDE/src/SourceEditor/StyleParser.cs b/CrowIDE/src/SourceEditor/StyleParser.cs
deleted file mode 100644 (file)
index 9a1e74c..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-using System;
-using Crow;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Text.RegularExpressions;
-using System.Linq;
-
-namespace Crow.Coding
-{
-       public class StyleParser : BufferParser
-       {
-               enum States { init, classNames, members, value, endOfStatement }
-
-               public StyleParser (CodeBuffer _buffer) : base(_buffer)
-               {
-               }
-
-               #region Character ValidityCheck
-               static Regex rxValidChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}");
-               static Regex rxNameStartChar = new Regex(@"_|\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}");                                                                                                                      
-               static Regex rxNameChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}");
-               static Regex rxDecimal = new Regex(@"[0-9]+");
-               static Regex rxHexadecimal = new Regex(@"[0-9a-fA-F]+");
-
-               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
-
-               States curState = States.classNames;
-
-               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 ParserException (currentLine, currentColumn, "Unexpected end of line");
-                                       Read ();
-                                       eol = true;
-                                       continue;
-                               }
-
-                               switch (Peek()) {
-                               case '/':
-                                       readToCurrTok (true);
-                                       switch (Peek ()) {
-                                       case '/':
-                                               currentTok += ReadLine ();
-                                               saveAndResetCurrentTok (TokenType.LineComment);
-                                               break;
-                                       default:
-                                               currentTok += ReadLine ();
-                                               saveAndResetCurrentTok (TokenType.Unknown);
-                                               break;
-                                       }
-                                       break;
-                               case ',':
-                                       if (curState != States.init && curState != States.classNames )
-                                               throw new ParserException (currentLine, currentColumn, "Unexpected char ','");
-                                       readAndResetCurrentTok (TokenType.OperatorOrPunctuation, true);
-                                       curState = States.classNames;
-                                       break;
-                               case '{':
-                                       if (!(curState == States.init || curState == States.classNames))
-                                               throw new ParserException (currentLine, currentColumn, "Unexpected char '{'");
-                                       readAndResetCurrentTok (TokenType.OpenBlock, true);
-                                       curState = States.members;
-                                       break;
-                               case '}':
-                                       if (curState != States.members)
-                                               throw new ParserException (currentLine, currentColumn, "Unexpected char '}'");
-                                       readAndResetCurrentTok (TokenType.CloseBlock, true);
-                                       curState = States.classNames;
-                                       break;
-                               case '=':
-                                       if (curState == States.classNames)
-                                               throw new ParserException (currentLine, currentColumn, "Unexpected char '='");
-                                       setPreviousTokOfTypeTo (TokenType.Type, TokenType.Identifier);
-                                       readAndResetCurrentTok (TokenType.OperatorOrPunctuation, true);
-                                       curState = States.value;
-                                       break;
-                               case '"':
-                                       if (curState != States.value)
-                                               throw new ParserException (currentLine, currentColumn, "Unexpected char '\"'");                                 
-                                       readAndResetCurrentTok (TokenType.StringLitteralOpening, true);
-
-                                       while (!eol) {
-                                               currentTok += ReadLineUntil ("\"");
-                                               if (currentTok.Content [currentTok.Content.Length - 1] == '\\')
-                                                       readToCurrTok ();
-                                               else
-                                                       break;
-                                       }
-                                       if (eol)
-                                               throw new ParserException (currentLine, currentColumn, "Unexpected end of line");
-                                       saveAndResetCurrentTok (TokenType.StringLitteral);
-
-                                       readAndResetCurrentTok (TokenType.StringLitteralClosing, true);
-                                       curState = States.endOfStatement;
-                                       break;
-                               case ';':
-                                       if (curState != States.endOfStatement)
-                                               throw new ParserException (currentLine, currentColumn, "Unexpected end of statement");                                  
-                                       readAndResetCurrentTok (TokenType.StatementEnding, true);
-                                       curState = States.members;
-                                       break;
-                               default:
-                                       if (currentTok.Type != TokenType.Unknown)
-                                               throw new ParserException (currentLine, currentColumn, "error curtok not null");
-                                       if (curState == States.value)
-                                               throw new ParserException (currentLine, currentColumn, "expecting value enclosed in '\"'");
-                                       if (curState == States.endOfStatement)
-                                               throw new ParserException (currentLine, currentColumn, "expecting end of statement");                                   
-                                       
-                                       if (nextCharIsValidCharStartName) {                                             
-                                               readToCurrTok (true);
-                                               while (nextCharIsValidCharName)
-                                                       readToCurrTok ();
-                                       }
-                                       saveAndResetCurrentTok (TokenType.Type);
-                                       break;
-                               }
-                       }
-
-                       if (cl.EndingState != (int)curState && currentLine < buffer.LineCount - 1)
-                               buffer [currentLine + 1].Tokens = null;
-
-                       cl.EndingState = (int)curState;
-               }
-               public override void SyntaxAnalysis ()
-               {
-                       initSyntaxAnalysis ();
-                       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 (cl.Tokens [tokPtr].Type) {
-                                       case TokenType.OpenBlock:                                               
-                                               currentNode = addChildNode (currentNode, cl, tokPtr, "style");
-                                               break;
-                                       case TokenType.CloseBlock:                                              
-                                               closeNodeAndGoUp (ref currentNode, cl, "style");
-                                               break;
-                                       }
-                                       tokPtr++;
-                               }
-                       }
-               }
-       }
-}
-
diff --git a/CrowIDE/src/SourceEditor/TextFormatting.cs b/CrowIDE/src/SourceEditor/TextFormatting.cs
deleted file mode 100644 (file)
index f7b2e51..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-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
deleted file mode 100644 (file)
index 8b4df5e..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-//
-//  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 BufferParser.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 IsNull { get { return IsEmpty && Type == BufferParser.TokenType.Unknown; }}
-               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
deleted file mode 100644 (file)
index d31e102..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-using System;
-using Crow;
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
-using System.Diagnostics;
-using System.Linq;
-
-namespace Crow.Coding
-{
-       public class XMLParser : BufferParser
-       {
-               public new enum TokenType {
-                       Unknown = BufferParser.TokenType.Unknown,
-                       WhiteSpace = BufferParser.TokenType.WhiteSpace,
-                       NewLine = BufferParser.TokenType.NewLine,
-                       LineComment = BufferParser.TokenType.LineComment,
-                       BlockCommentStart = BufferParser.TokenType.BlockCommentStart,
-                       BlockComment = BufferParser.TokenType.BlockComment,
-                       BlockCommentEnd = BufferParser.TokenType.BlockCommentEnd,
-                       ElementName = BufferParser.TokenType.Identifier,
-                       AttributeName = BufferParser.TokenType.Keyword,
-                       ElementClosing = BufferParser.TokenType.StatementEnding,
-                       Affectation = BufferParser.TokenType.OperatorOrPunctuation,
-                       AttributeValueOpening = BufferParser.TokenType.StringLitteralOpening,
-                       AttributeValueClosing = BufferParser.TokenType.StringLitteralClosing,
-                       AttributeValue = BufferParser.TokenType.StringLitteral,
-                       XMLDecl = BufferParser.TokenType.Preprocessor,
-                       ElementStart = 50,
-                       ElementEnd = 51,
-               }
-
-               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 (ParserException 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 ParserException (currentLine, currentColumn, "Unexpected end of line");
-                                       Read ();
-                                       eol = true;
-                                       continue;
-                               }
-
-                               if (curState == States.BlockComment) {
-                                       if (currentTok != TokenType.Unknown)
-                                               Debugger.Break ();
-
-                                       currentTok.Start = CurrentPosition;
-                                       currentTok.Type = (BufferParser.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 ParserException (currentLine, currentColumn, "xml decl may appear only on first line");
-                                               readToCurrTok ();
-                                               currentTok += ReadLineUntil ("?>");
-                                               if (Peek (2) != "?>")
-                                                       throw new ParserException (currentLine, currentColumn, "expecting '?>'");
-                                               readToCurrTok (2);
-                                               saveAndResetCurrentTok (TokenType.XMLDecl);
-                                               curState = States.prolog;
-                                               break;
-                                       case '!':
-                                               readToCurrTok ();
-                                               switch (Peek()) {
-                                               case '-':
-                                                       readToCurrTok ();
-                                                       if (Peek () != '-')
-                                                               throw new ParserException (currentLine, currentColumn, "Expecting comment start tag");
-                                                       readToCurrTok ();
-                                                       currentTok += ReadLineUntil ("--");
-                                                       if (Peek (3) == "-->") {
-                                                               readToCurrTok (3);
-                                                       }else
-                                                               curState = States.BlockComment;
-                                                       saveAndResetCurrentTok (TokenType.BlockComment);
-                                                       break;
-                                               default:
-                                                       throw new ParserException (currentLine, currentColumn, "error");
-                                               }
-                                               break;
-                                       default:
-                                               if (!(curState == States.Content || curState == States.XML || curState == States.init || curState == States.prolog))
-                                                       throw new ParserException (currentLine, currentColumn, "Unexpected char: '<'");
-                                               if (Peek () == '/') {
-                                                       curState = States.EndTag;
-                                                       readToCurrTok ();
-                                                       saveAndResetCurrentTok (TokenType.ElementEnd);
-                                               } else {
-                                                       curState = States.StartTag;
-                                                       saveAndResetCurrentTok (TokenType.ElementStart);
-                                               }
-
-                                               if (!nextCharIsValidCharStartName)
-                                                       throw new ParserException (currentLine, currentColumn, "Expected element name");
-
-                                               readToCurrTok (true);
-                                               while (nextCharIsValidCharName)
-                                                       readToCurrTok ();
-
-                                               saveAndResetCurrentTok (TokenType.ElementName);
-                                               break;
-                                       }
-                                       break;
-                               case '/':
-                                       if (curState != States.StartTag)
-                                               throw new ParserException (currentLine, currentColumn, "Unexpected char: '/'");
-                                       readToCurrTok (true);
-                                       if (Peek () != '>')
-                                               throw new ParserException (currentLine, currentColumn, "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 ParserException (currentLine, currentColumn, "Unexpected char: '>'");
-                                       }
-                                       break;
-                               default:
-                                       switch (curState) {
-                                       case States.StartTag:
-                                               if (!nextCharIsValidCharStartName)
-                                                       throw new ParserException (currentLine, currentColumn, "Expected attribute name");
-                                               readToCurrTok (true);
-                                               while (nextCharIsValidCharName)
-                                                       readToCurrTok ();
-                                               saveAndResetCurrentTok (TokenType.AttributeName);
-
-                                               SkipWhiteSpaces ();
-
-                                               if (Peek () != '=')
-                                                       throw new ParserException (currentLine, currentColumn, "Expecting: '='");
-                                               readAndResetCurrentTok (TokenType.Affectation, true);
-
-                                               SkipWhiteSpaces ();
-
-                                               char openAttVal = Peek ();
-                                               if (openAttVal != '"' && openAttVal != '\'')
-                                                       throw new ParserException (currentLine, currentColumn, "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 ParserException (currentLine, currentColumn, string.Format ("Expecting {0}", openAttVal));
-                                               readAndResetCurrentTok (TokenType.AttributeValueClosing, true);
-                                               break;
-                                       default:
-                                               throw new ParserException (currentLine, currentColumn, "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 ()
-               {
-                       initSyntaxAnalysis ();
-                       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++;
-                                               currentNode = addChildNode (currentNode, cl, tokPtr, "Element");
-                                               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 ParserException (currentLine, currentColumn, "Closing tag mismatch");
-                                               }
-                                               closeNodeAndGoUp (ref currentNode, cl, "Element");
-                                               break;
-                                       case TokenType.ElementClosing:
-                                               //currentNode = currentNode.Parent;
-                                               break;
-                                       default:
-                                               break;
-                                       }
-                                       tokPtr++;
-                               }
-                       }
-               }
-       }
-}
-
diff --git a/CrowIDE/src/SvgEditor.cs b/CrowIDE/src/SvgEditor.cs
deleted file mode 100644 (file)
index 219eea6..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-//
-// SvgEditor.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.ComponentModel;
-using Cairo;
-
-namespace Crow.Coding
-{
-       public class SvgEditor : Editor
-       {
-               SvgPicture _pic = new SvgPicture();
-
-               int zoom;
-
-               [DefaultValue(100)]
-               public int Zoom {
-                       get { return zoom; }
-                       set {
-                               if (zoom == value)
-                                       return;
-                               zoom = value;
-                               NotifyValueChanged ("Zoom", zoom);
-                               updateMaxScrolls ();
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-
-               void updateMaxScrolls() {                       
-                       MaxScrollX = Math.Max(0, _pic.Dimensions.Width * zoom / 100 - Slot.Width);
-                       MaxScrollY = Math.Max(0, _pic.Dimensions.Height * zoom / 100 - Slot.Height);
-
-                       if (Slot.Width + MaxScrollX > 0)
-                               NotifyValueChanged ("ChildWidthRatio", Slot.Width * Slot.Width / (Slot.Width + MaxScrollX));
-                       else
-                               NotifyValueChanged ("ChildWidthRatio", 0);
-                       
-                       if (Slot.Height + MaxScrollY > 0)
-                               NotifyValueChanged ("ChildHeightRatio", Slot.Height * Slot.Height / (Slot.Height + MaxScrollY));
-                       else
-                               NotifyValueChanged ("ChildHeightRatio", 0);
-               }
-               #region editor overrides
-               protected override void updateEditorFromProjFile ()
-               {
-                       Error = null;
-                       try {
-                               editorMutex.EnterWriteLock();
-                               _pic.LoadSvgFragment (projFile.Source);
-                               _pic.Scaled = true;
-                               _pic.KeepProportions = true;
-                       } catch (Exception ex) {
-                               Error = ex;
-                       }
-                       editorMutex.ExitWriteLock ();
-                       updateMaxScrolls ();
-                       RegisterForGraphicUpdate ();
-               }
-               protected override void updateProjFileFromEditor ()
-               {
-                       throw new NotImplementedException ();
-               }
-               protected override bool EditorIsDirty {
-                       get { return false;     }
-                       set {
-                               throw new NotImplementedException ();
-                       }
-               }
-               #endregion
-
-               #region GraphicObject overrides
-               protected override int measureRawSize (LayoutingType lt)
-               {
-                       if (_pic == null)
-                               return 2 * Margin;
-                       //_pic = "#Crow.Images.Icons.IconAlerte.svg";
-                       //TODO:take scalling in account
-                       if (lt == LayoutingType.Width)
-                               return _pic.Dimensions.Width + 2 * Margin;
-                       else
-                               return _pic.Dimensions.Height + 2 * Margin;
-               }
-               protected override void onDraw (Context gr)
-               {
-                       base.onDraw (gr);
-
-                       Rectangle r = ClientRectangle;
-                       Foreground.SetAsSource (gr, r);
-                       gr.Rectangle (r, 0.1);
-                       gr.Stroke ();
-
-                       r.Width = _pic.Dimensions.Width * zoom / 100;
-                       r.Height = _pic.Dimensions.Height * zoom / 100;
-
-                       gr.Save ();
-
-                       editorMutex.EnterReadLock ();
-
-                       gr.Translate (-ScrollX, -ScrollY);
-                       if (_pic != null)
-                               _pic.Paint (gr, r);
-                       editorMutex.ExitReadLock ();
-
-                       gr.Restore ();
-               }
-               public override void OnLayoutChanges (LayoutingType layoutType)
-               {
-                       base.OnLayoutChanges (layoutType);
-                       if ((layoutType | LayoutingType.Sizing) > 0)
-                               updateMaxScrolls ();
-               }
-               #endregion
-       }
-}
-
diff --git a/CrowIDE/ui/ContextMenu.template b/CrowIDE/ui/ContextMenu.template
new file mode 100644 (file)
index 0000000..2b03d1f
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<MenuItem MinimumSize="20,20" Height="Fit" Width="160" Caption="Context Menu" Data="{ContextCommands}" Orientation="Vertical"
+       IsOpened ="true" Visible="{/IsOpened}" SelectionBackground="Transparent">
+       <Template>              
+               <Border Background="DimGray" Foreground="Black" CornerRadius="2">
+                       <GenericStack Orientation="{./Orientation}" Name="ItemsContainer" Margin="2"/>
+               </Border>               
+       </Template>
+       <ItemTemplate>
+               <MenuItem Command="{}" Width="150" PopWidth="120" SelectionBackground="Transparent" IsEnabled="{CanExecute}">
+                       <Template>
+                               <Popper Font="{./Font}" Caption="{./Caption}"  Background="{./Background}" PopDirection="{./PopDirection}"
+                                       Foreground = "{./Foreground}" CanPop="{./HasChildren}" MouseDown="./onMI_Click"
+                                       IsPopped="{²./IsOpened}" PopWidth="{./PopWidth}" PopHeight="{./PopHeight}">
+                                       <Template>
+                                               <Border Name="border1"
+                                                               CornerRadius="0"
+                                                               MouseEnter="{Foreground=vgradient|0:White|0.2:Gray|0.9:Gray|1:Black}"
+                                                               MouseLeave="{Foreground=Transparent}"
+                                                               MouseDown="{Foreground=vgradient|0:Black|0.05:Gray|0.85:Gray|1:White}"
+                                                               MouseUp="{Foreground=vgradient|0:White|0.2:Gray|0.9:Gray|1:Black}"
+                                                               MinimumSize = "60,0"
+                                                               Foreground="Transparent"
+                                                               Background="{./Background}">
+                                                               <HorizontalStack Spacing="5">
+                                                                       <Image Height="14" Width="14" Picture="{Icon}" />
+                                                                       <Label Text="{./Caption}"
+                                                                               Foreground="{./Foreground}"
+                                                                               Margin="1" HorizontalAlignment="Left"
+                                                                               Font="{./Font}" />
+                                                               </HorizontalStack>
+                                               </Border>
+                                       </Template>
+                                       <Border Foreground="DimGray" Width="{../PopWidth}" Height="{../PopHeight}" Background="Onyx">
+                                               <VerticalStack Name="ItemsContainer"/>
+                                       </Border>
+                               </Popper>
+                       </Template>
+               </MenuItem>
+       </ItemTemplate>
+</MenuItem>
+
index 02aa6fd8855414ee6d861ab2b1b3650d171aaab3..94a57e718eb7648628b6381fad999a51441b777f 100644 (file)
@@ -5,6 +5,7 @@
                        <MenuItem Caption="File" Width="Fit" PopWidth="120" DataSource="{CurrentSolution}">
                                <MenuItem Command="{CMDNew}" />
                                <MenuItem Command="{CMDOpen}" />
+                               <MenuItem Command="{cmdCloseSolution}" />
                                <MenuItem DataSource="{SelectedItem}" Command="{cmdSave}" />
                                <MenuItem DataSource="{SelectedItem}" Command="{cmdSaveAs}" />
                                <MenuItem Command="{CMDQuit}" />
index d6b1bd4c5a9ed62b688690ac3cb9e2ef9d6be5fc..9059c7a4874a7d598a3bffeffb099e0c51850afd 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0"?>
 <DockWindow DataSource="{CurrentSolution}" Name="winToolbox" Caption="Toolbox" Width="10%" Height="80%">
-       <ListBox Margin="10" Data="{ToolboxItems}" SelectionBackground="SkyBlue">
+       <ListBox Margin="3" Data="{ToolboxItems}" SelectionBackground="SkyBlue">
                <Template>
-                       <Wrapper Name="ItemsContainer" Orientation="Vertical" Margin="10" Spacing="3"/>
+                       <Wrapper Name="ItemsContainer" Orientation="Vertical" Spacing="0"/>
                </Template>
                <ItemTemplate>
                        <Container Fit="true" Focusable="true" Tooltip="{DisplayName}" Margin="2" AllowDrag="true"
@@ -11,7 +11,7 @@
                                        Foreground="Transparent" BorderWidth="1"
                                        MouseDown="{Foreground=vgradient|0:Black|0.05:Gray|0.85:Gray|1:White}"
                                        MouseUp="{Foreground=vgradient|0:White|0.2:Gray|0.9:Gray|1:Black}">
-                                       <Image Path="{IconPath}" Margin="2"  Width="20" Height="20" />
+                                       <Image Path="{IconPath}" Margin="3"  Width="20" Height="20" />
                                </Border>
                        </Container>
                </ItemTemplate>
diff --git a/CrowIDE/ui/EditPane.template b/CrowIDE/ui/EditPane.template
deleted file mode 100644 (file)
index 43be10d..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<TabView SelectedTab="{²./SelectedIndex}" Name="ItemsContainer" Orientation="Horizontal" />
diff --git a/CrowIDE/ui/EditPaneItems.template b/CrowIDE/ui/EditPaneItems.template
deleted file mode 100644 (file)
index d0c0922..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0"?>
-<ItemTemplate> 
-       <TabItem Caption="{DisplayName}" QueryClose="OnQueryClose">
-               <Label Text="Error" Background="Red"/>
-       </TabItem>
-</ItemTemplate>
-<ItemTemplate DataType=".svg">
-       <TabItem Caption="{DisplayName}" QueryClose="OnQueryClose">
-               <VerticalStack>
-                       <HorizontalStack Height="50%" >
-                               <SvgEditor Margin="10" ProjectNode="{}" Focusable="true" Name="editor" MouseWheelSpeed="20" Foreground="Black"/>
-                               <ScrollBar Name="scrollbarY" Value="{²../editor.ScrollY}"
-                                                  LargeIncrement="10"
-                                                  CursorSize="{../editor.ChildHeightRatio}"
-                                       Maximum="{../editor.MaxScrollY}" Orientation="Vertical"
-                                       Width="14" />
-                       </HorizontalStack>
-                       <ScrollBar Style="HScrollBar" Name="scrollbarX" Value="{²../editor.ScrollX}"
-                                       Maximum="{../editor.MaxScrollX}" Orientation="Horizontal"
-                                       LargeIncrement="10"
-                                       CursorSize="{../editor.ChildWidthRatio}"
-                                       Height="14" />
-                       <HorizontalStack Height="Fit" Margin="3">
-                               <Label Text="Zoom:"/>
-                               <Label Text="{../../editor.Zoom}" Fit="true"/>
-                               <!--<Spinner Name="sldZoom" Value="{²../../editor.Zoom}" Maximum="800" Minimum="1" SmallIncrement="10" LargeIncrement="50" Width="40" />-->
-                               <Slider Value="{²../../editor.Zoom}" CursorSize="2" Height="8" Maximum="800" Minimum="1" SmallIncrement="1" LargeIncrement="10" Width="100" />
-                       </HorizontalStack>
-
-                       <Splitter/>
-                       <IMLContainer Path="#Crow.Coding.ui.SourceEditor.crow"/>
-                       <Label DataSource="{../editor.Error}" Text="{Message}"
-                               Visible="{../editor.HasError}"
-                               Height="Fit" Width="Stretched" Background="DarkRed" Foreground="White"
-                               TextAlignment="TopLeft" Multiline="true"/>
-               </VerticalStack>
-       </TabItem>
-</ItemTemplate>
-<ItemTemplate Path="#Crow.Coding.ui.SrcEdit.itemp" DataType=".cs"/>
-<ItemTemplate Path="#Crow.Coding.ui.SrcEdit.itemp" DataType=".style"/>
-<ItemTemplate Path="#Crow.Coding.ui.IMLEdit.itemp" DataType=".crow"/>
-<ItemTemplate Path="#Crow.Coding.ui.IMLEdit.itemp" DataType=".template"/>
index 4be4f09413cb4964aea894639dacc7f0b4508506..d3447366857b46a46d5a5d10a3b412d3959579cf 100644 (file)
@@ -1,28 +1,29 @@
 <?xml version="1.0"?>
-<Expandable Caption="{Name}" >
+<Expandable Caption="{Name}" IsExpanded="{²IsExpanded}">
        <Template>
                <VerticalStack>
-                       <HorizontalStack Spacing="1" Height="Fit" MouseDoubleClick="./onClickForExpand" Background="{./Background}">
-                               <Container Margin="1" Width="10" Height="10" Focusable="true" MouseClick="./onClickForExpand"
-                                       MouseEnter="{Background=LightGray}"
-                                       MouseLeave="{Background=Transparent}">
-                                       <Image
+                       <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"                                          
+                                       Foreground="Transparent"
+                                       MouseEnter="{Foreground=DimGray}"
+                                       MouseLeave="{Foreground=Transparent}">
+                               <HorizontalStack Spacing="1">
+                                       <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
                                                Path="{./Image}"
                                                Visible="{./IsExpandable}"
-                                               SvgSub="{./IsExpanded}"/>
-                               </Container>
-                               <Image Margin="2" Width="14" Height="14"
-                                       Path="#Crow.Icons.folder.svg"/>
-                               <Label Text="{./Caption}"
-                                               MouseEnter="{Background=hgradient|0:BlueCrayola|1:Transparent}"
+                                               SvgSub="{./IsExpanded}"
+                                               MouseEnter="{Background=LightGray}"
                                                MouseLeave="{Background=Transparent}"/>
-                       </HorizontalStack>
+                                       <Border Width="16" Height="16" Foreground="Black" Background="White">
+                                               <Image Margin="2" Path="{GetIcon}" />
+                                       </Border>
+                                       <Label Text="{./Caption}"/>
+                               </HorizontalStack>
+                       </Border>
                        <Container Name="Content" Visible="false"/>
                </VerticalStack>
        </Template>
        <HorizontalStack Height="Fit">
-               <GraphicObject Width="12" Height="10"/>
-               <TreeView Name="List" Height="Fit"
-                       Template="#Crow.Templates.treeList.template" />
+               <GraphicObject Width="8" Height="10"/>
+               <VerticalStack Height="Fit" Name="ItemsContainer"/>
        </HorizontalStack>
 </Expandable>
index b62b02a1725ab57cf1553637e0c1d6afa7e81ec5..a4d5f727c311672ee10e3f7ece93658e09c3c9c9 100644 (file)
@@ -1,30 +1,18 @@
 <?xml version="1.0"?>
-<Window Caption="Graphic Tree" Width="20%" Height="70%" AlwaysOnTop="true">
-       <VerticalStack>
+<DockWindow Name="winGTExplorer" Caption="Edit View" Width="40%" Height="80%">
+       <VerticalStack Name="vstack" DataSource="{CurrentSolution}">
                <Button Caption="Expand All" MouseClick="../treeView.onExpandAll_MouseClick"/>          
-               <TreeView IsRoot="true" Name="treeView" Data="{GraphicTree}"
-                       SelectedItemChanged="GTView_SelectedItemChanged">
-<!--                   <Template>
-                               <HorizontalStack>
-                                       <Scroller  Name="scroller1" Margin="1" VerticalScrolling="true"
-                                               Background="{./Background}"
-                                               ScrollY="{../scrollbar1.Value}">
-                                               <VerticalStack
-                                                       Height="Fit" Name="ItemsContainer" Margin="0" VerticalAlignment="Top"/>
-                                       </Scroller>
-                                       <ScrollBar
-                                               Name="scrollbar1"
-                                               Value="{../scroller1.ScrollY}"
-                                               Maximum="{../scroller1.MaximumScroll}"
-                                               Width="12" Orientation="Vertical"/>
-                               </HorizontalStack>
-                       </Template>-->
+               <TreeView DataSource="{SelectedItem}" IsRoot="true" Name="treeView" Data="{GraphicTree}"
+                       SelectedItemChanged="../../vstack.DataSource.GTView_SelectedItemChanged">
                        <ItemTemplate>
-                               <HorizontalStack Width="Stretched" Focusable="true">
-                                       <Label Text="{Name}"
-                                                       MouseEnter="{Background=hgradient|0:BlueCrayola|1:Transparent}"
-                                                       MouseLeave="{Background=Transparent}"/>
-                               </HorizontalStack>
+                               <Border Width="Stretched" Focusable="true" Foreground="Transparent">
+                                       <HorizontalStack Spacing="5">
+                                               <Border Width="16" Height="16" Foreground="Black" Background="White">
+                                                       <Image Margin="2" Path="{GetIcon}" />
+                                               </Border>
+                                               <Label Text="{Name}" Width="Stretched"/>
+                                       </HorizontalStack>
+                               </Border>
                        </ItemTemplate>
                        <ItemTemplate DataType="Crow.Group" Data="GetChildren"
                                Path="#Crow.Coding.ui.GTreeExpITemp.crow"/>
@@ -36,4 +24,4 @@
                                Path="#Crow.Coding.ui.GTreeExpITemp.crow"/>
                </TreeView>
        </VerticalStack>
-</Window>
+</DockWindow>
diff --git a/CrowIDE/ui/IMLEdit.itemp b/CrowIDE/ui/IMLEdit.itemp
deleted file mode 100644 (file)
index 5f75bdc..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<TabItem Caption="{DisplayName}" QueryClose="OnQueryClose">
-       <VerticalStack>
-               <Label Width="Stretched" Margin="1" Text="{HoverWidget}"/>
-               <ImlVisualEditor Height="60%" Margin="0" MinimumSize="10,10" Foreground="SkyBlue"
-                       AllowDrop="true"
-                       ProjectNode="{}" SelectedItem="{²SelectedItem}"
-                       Name="crowContainer" Background="Onyx"/>
-               <Label DataSource="{../crowContainer.Error}" Text="{Message}"
-                       Visible="{../crowContainer.HasError}"
-                       Height="Fit" Width="Stretched" Background="DarkRed" Foreground="White"
-                       TextAlignment="TopLeft" Multiline="true"/>
-               <Splitter/>
-               <IMLContainer Path="#Crow.Coding.ui.SourceEditor.crow"/>
-       </VerticalStack>
-</TabItem>
diff --git a/CrowIDE/ui/SourceEditor.crow b/CrowIDE/ui/SourceEditor.crow
deleted file mode 100644 (file)
index 75136ef..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<VerticalStack>
-       <HorizontalStack Height="Stretched" >
-               <SourceEditor Focusable="true" Name="editor" Font="monospace, 12" VerticalAlignment="Top" Margin="10"
-                               CurrentLine="{²CurrentLine}" CurrentColumn="{²CurrentColumn}"
-                               Foreground="Jet" Background="White" Width="Stretched" Height="Stretched"
-                               ProjectNode="{}"  KeyDown="textView_KeyDown"/>
-               <ScrollBar Name="scrollbarY" Value="{²../editor.ScrollY}"
-                                  LargeIncrement="{../editor.VisibleLines}"
-                                  CursorSize="{../editor.ChildHeightRatio}"
-                       Maximum="{../editor.MaxScrollY}" Orientation="Vertical"
-                       Width="14" />
-       </HorizontalStack>
-       <ScrollBar Style="HScrollBar" Name="scrollbarX" Value="{²../editor.ScrollX}"
-                       Maximum="{../editor.MaxScrollX}" Orientation="Horizontal"
-                       LargeIncrement="{../editor.VisibleColumns}"
-                       CursorSize="{../editor.ChildWidthRatio}"
-                       Height="14" />                  
-       <HorizontalStack Height="Fit">
-               <GraphicObject Height="5" Width="Stretched"/>
-               <GraphicObject Background="Red" Width="5" Height="5" Visible="{IsDirty}"/>
-               <Label Text="Line:" Foreground="Gray"/>
-               <Label Text="{CurrentLine}"/>
-               <GraphicObject Height="5" Width="10"/>
-               <Label Text="column:" Foreground="Gray"/>
-               <Label Text="{CurrentColumn}"/>
-               <GraphicObject Height="5" Width="10"/>
-               <Label Text="ScrollX:" Foreground="Gray"/>
-               <Label Text="{../../editor.ScrollX}"/>
-       </HorizontalStack>
-</VerticalStack>
diff --git a/CrowIDE/ui/SrcEdit.itemp b/CrowIDE/ui/SrcEdit.itemp
deleted file mode 100644 (file)
index ec67b55..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<TabItem Caption="{DisplayName}" QueryClose="OnQueryClose">
-       <IMLContainer Path="#Crow.Coding.ui.SourceEditor.crow"/>
-</TabItem>
\ No newline at end of file
diff --git a/CrowIDE/ui/editors/EditPane.template b/CrowIDE/ui/editors/EditPane.template
new file mode 100644 (file)
index 0000000..43be10d
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<TabView SelectedTab="{²./SelectedIndex}" Name="ItemsContainer" Orientation="Horizontal" />
diff --git a/CrowIDE/ui/editors/EditPaneItems.template b/CrowIDE/ui/editors/EditPaneItems.template
new file mode 100644 (file)
index 0000000..9cc1880
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<ItemTemplate> 
+       <TabItem Caption="{DisplayName}" QueryClose="OnQueryClose">
+               <Label Text="Error" Background="Red"/>
+       </TabItem>
+</ItemTemplate>
+<ItemTemplate Path="#Crow.Coding.ui.SvgEdit.itemp" DataType=".svg"/>
+<ItemTemplate Path="#Crow.Coding.ui.SrcEdit.itemp" DataType=".cs"/>
+<ItemTemplate Path="#Crow.Coding.ui.SrcEdit.itemp" DataType=".style"/>
+<ItemTemplate Path="#Crow.Coding.ui.IMLEdit.itemp" DataType=".crow"/>
+<ItemTemplate Path="#Crow.Coding.ui.IMLEdit.itemp" DataType=".template"/>
diff --git a/CrowIDE/ui/editors/IMLEdit.itemp b/CrowIDE/ui/editors/IMLEdit.itemp
new file mode 100644 (file)
index 0000000..cbef652
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<TabItem Caption="{DisplayName}" QueryClose="OnQueryClose">
+       <VerticalStack>
+               <Label Width="Stretched" Margin="1" Text="{HoverWidget}"/>
+               <ImlVisualEditor Height="60%" Margin="0" MinimumSize="10,10" Foreground="SkyBlue"
+                       AllowDrop="true" UpdateEnabled="{../../IsSelected}"
+                       ProjectNode="{}" SelectedItem="{²SelectedItem}"
+                       Name="crowContainer" Background="Onyx"/>
+               <Splitter/>
+               <IMLContainer Path="#Crow.Coding.ui.SourceEditor.crow"/>
+               <Label DataSource="{../crowContainer.Error}" Text="{Message}"
+                       Visible="{../crowContainer.HasError}"
+                       Height="Fit" Width="Stretched" Background="DarkRed" Foreground="White"
+                       TextAlignment="TopLeft" Multiline="true"/>
+       </VerticalStack>
+</TabItem>
diff --git a/CrowIDE/ui/editors/SourceEditor.crow b/CrowIDE/ui/editors/SourceEditor.crow
new file mode 100644 (file)
index 0000000..32f137f
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<VerticalStack>
+       <HorizontalStack >
+               <SourceEditor Focusable="true" Name="editor" Font="monospace, 12" VerticalAlignment="Top" Margin="10"
+                               CurrentLine="{²CurrentLine}" CurrentColumn="{²CurrentColumn}"
+                               Foreground="Jet" Background="White" Width="Stretched" Height="Stretched"
+                               ProjectNode="{}"  KeyDown="textView_KeyDown"/>
+               <ScrollBar Name="scrollbarY" Value="{²../editor.ScrollY}"
+                                  LargeIncrement="{../editor.VisibleLines}"
+                                  CursorSize="{../editor.ChildHeightRatio}"
+                       Maximum="{../editor.MaxScrollY}" Orientation="Vertical"
+                       Width="14" />
+       </HorizontalStack>
+       <ScrollBar Style="HScrollBar" Name="scrollbarX" Value="{²../editor.ScrollX}"
+                       Maximum="{../editor.MaxScrollX}" Orientation="Horizontal"
+                       LargeIncrement="{../editor.VisibleColumns}"
+                       CursorSize="{../editor.ChildWidthRatio}"
+                       Height="14" />                  
+       <HorizontalStack Height="Fit">
+               <GraphicObject Height="5" Width="Stretched"/>
+               <GraphicObject Background="Red" Width="5" Height="5" Visible="{IsDirty}"/>
+               <Label Text="Line:" Foreground="Gray"/>
+               <Label Text="{CurrentLine}"/>
+               <GraphicObject Height="5" Width="10"/>
+               <Label Text="column:" Foreground="Gray"/>
+               <Label Text="{CurrentColumn}"/>
+               <GraphicObject Height="5" Width="10"/>
+               <Label Text="ScrollX:" Foreground="Gray"/>
+               <Label Text="{../../editor.ScrollX}"/>
+       </HorizontalStack>
+</VerticalStack>
diff --git a/CrowIDE/ui/editors/SrcEdit.itemp b/CrowIDE/ui/editors/SrcEdit.itemp
new file mode 100644 (file)
index 0000000..ec67b55
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<TabItem Caption="{DisplayName}" QueryClose="OnQueryClose">
+       <IMLContainer Path="#Crow.Coding.ui.SourceEditor.crow"/>
+</TabItem>
\ No newline at end of file
diff --git a/CrowIDE/ui/editors/SvgEdit.itemp b/CrowIDE/ui/editors/SvgEdit.itemp
new file mode 100644 (file)
index 0000000..453ba95
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<TabItem Caption="{DisplayName}" QueryClose="OnQueryClose">
+       <VerticalStack>
+               <VerticalStack Height="50%">
+                       <HorizontalStack >
+                               <SvgEditor Margin="10" ProjectNode="{}" Focusable="true" Name="editor" MouseWheelSpeed="20" Foreground="Black"/>
+                               <ScrollBar Name="scrollbarY" Value="{²../editor.ScrollY}"
+                                                  LargeIncrement="10"
+                                                  CursorSize="{../editor.ChildHeightRatio}"
+                                       Maximum="{../editor.MaxScrollY}" Orientation="Vertical"
+                                       Width="14" />
+                       </HorizontalStack>
+                       <ScrollBar Style="HScrollBar" Name="scrollbarX" Value="{²../editor.ScrollX}"
+                                       Maximum="{../editor.MaxScrollX}" Orientation="Horizontal"
+                                       LargeIncrement="10"
+                                       CursorSize="{../editor.ChildWidthRatio}"
+                                       Height="14" />
+                       <HorizontalStack Height="Fit" Margin="3">
+                               <Label Text="Zoom:"/>
+                               <Label Text="{../../editor.Zoom}" Fit="true"/>
+                               <!--<Spinner Name="sldZoom" Value="{²../../editor.Zoom}" Maximum="800" Minimum="1" SmallIncrement="10" LargeIncrement="50" Width="40" />-->
+                               <Slider Value="{²../../editor.Zoom}" CursorSize="2" Height="8" Maximum="800" Minimum="1" SmallIncrement="1" LargeIncrement="10" Width="100" />
+                       </HorizontalStack>
+               </VerticalStack>
+               <Splitter/>
+               <IMLContainer Path="#Crow.Coding.ui.SourceEditor.crow"/>
+               <Label DataSource="{../editor.Error}" Text="{Message}"
+                       Visible="{../editor.HasError}"
+                       Height="Fit" Width="Stretched" Background="DarkRed" Foreground="White"
+                       TextAlignment="TopLeft" Multiline="true"/>
+       </VerticalStack>
+</TabItem>
\ No newline at end of file
index f91a982c764a61ee5cdada1a7d9ae8da36fc99ba..1253ff72b6804affb0aca58401bb581455c18459 100644 (file)
@@ -269,7 +269,7 @@ namespace Crow
                        Stream s;
 
                        if (!string.IsNullOrEmpty (VertSourcePath)) {
-                               s = Crow.Interface.GetStreamFromPath (VertSourcePath);
+                               s = Crow.Interface.StaticGetStreamFromPath (VertSourcePath);
                                if (s != null) {
                                        using (StreamReader sr = new StreamReader (s)) {
                                                vertSource = sr.ReadToEnd ();
@@ -278,7 +278,7 @@ namespace Crow
                        }
 
                        if (!string.IsNullOrEmpty (FragSourcePath)) {
-                               s = Crow.Interface.GetStreamFromPath (FragSourcePath);
+                               s = Crow.Interface.StaticGetStreamFromPath (FragSourcePath);
                                if (s != null) {
                                        using (StreamReader sr = new StreamReader (s)) {
                                                fragSource = sr.ReadToEnd ();
@@ -287,7 +287,7 @@ namespace Crow
                        }
 
                        if (!string.IsNullOrEmpty (GeomSourcePath)) {
-                               s = Crow.Interface.GetStreamFromPath (GeomSourcePath);
+                               s = Crow.Interface.StaticGetStreamFromPath (GeomSourcePath);
                                if (s != null) {
                                        using (StreamReader sr = new StreamReader (s)) {
                                                geomSource = sr.ReadToEnd ();
index ce24808b4daab8e55a852ea890946052190c7a99..08215ada2ed21fd0ed514dd024f97d1ec25fc6ac 100644 (file)
@@ -37,7 +37,7 @@ namespace Crow
                        
                public Texture(string _mapPath, bool flipY = true)
         {
-                       using (Stream s = Interface.GetStreamFromPath (_mapPath)) {
+                       using (Stream s = Interface.StaticGetStreamFromPath (_mapPath)) {
 
                                try {
                                        Map = _mapPath;
index b827161514f4ee9b877f31a8d7ab8f2eac568a98..e3af9c79781761a5a6abb6fdffce3788b3a17470 100644 (file)
@@ -55,7 +55,7 @@ namespace Crow
                /// load the image for rendering from the path given as argument
                /// </summary>
                /// <param name="path">image path, may be embedded</param>
-               public override void Load (string path)
+               public override void Load (Interface iface, string path)
                {
                        Path = path;
                        if (sharedResources.ContainsKey (path)) {
@@ -64,11 +64,8 @@ namespace Crow
                                Dimensions = sp.Dims;
                                return;
                        }
-                       using (Stream stream = Interface.GetStreamFromPath (path)) {
-                               using (MemoryStream ms = new MemoryStream ()) {
-                                       stream.CopyTo (ms);
-                                       loadBitmap (new System.Drawing.Bitmap (ms));    
-                               }
+                       using (Stream stream = iface.GetStreamFromPath (path)) {                                
+                               loadBitmap (new System.Drawing.Bitmap (stream));        
                        }
                        sharedResources [path] = new sharedPicture (image, Dimensions);
                }
index 12a020ffa73c9d1f8b24a96a67764768f7f0678e..e315f7616d951cfa8f0c267186ca559f3280a1ca 100644 (file)
@@ -276,7 +276,11 @@ namespace Crow.IML
 
                #region Reflexion helpers
                static MemberInfo getMemberInfoWithReflexion(object instance, string member){
-                       return instance.GetType ().GetMember (member)?.FirstOrDefault();
+                       Type t = instance.GetType();
+                       MemberInfo mi = t.GetMember (member)?.FirstOrDefault();
+                       if (mi == null)
+                               mi = CompilerServices.SearchExtMethod (t, member);
+                       return mi;
                }
                static MethodInfo getMethodInfoWithReflexion(object instance, string method){
                        return instance.GetType ().GetMethod (method, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
@@ -344,12 +348,20 @@ namespace Crow.IML
                                        PropertyInfo pi = mi as PropertyInfo;
                                        tmp = pi.GetValue (instance);
                                        dstType = pi.PropertyType;
-                               }
-                               if (mi.MemberType == MemberTypes.Field) {
+                               }else if (mi.MemberType == MemberTypes.Field) {
                                        FieldInfo fi = mi as FieldInfo;
                                        tmp = fi.GetValue (instance);
                                        dstType = fi.FieldType;
+                               }else if (mi.MemberType == MemberTypes.Method) {
+                                       MethodInfo gi = mi as MethodInfo;
+                                       if (gi.IsStatic)
+                                               tmp = gi.Invoke(null, new object[] {instance});
+                                       else
+                                               tmp = gi.Invoke(instance, null);
+                                       dstType = gi.ReturnType;
                                }
+
+
                                if (tmp != null)
                                        return tmp;
                                if (dstType == typeof(string) || dstType == CompilerServices.TObject)//TODO:object should be allowed to return null and not ""
@@ -693,7 +705,7 @@ namespace Crow.IML
                /// <summary>
                /// create delegate helper
                /// </summary>
-               static Delegate createDel(Type eventType, object instance, string method){
+               static Delegate createDel(object instance, Type eventType, string method){
                        Type t = instance.GetType ();
                        MethodInfo mi = t.GetMethod (method, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                        if (mi == null) {
index d74488743e617abda11acbd17345ca990f4d366d..cb662c51dc2aaebd9f6781896422867c5b28584e 100644 (file)
@@ -144,7 +144,12 @@ namespace Crow
                                handler(sender, e);
                        }
                }
-
+               public static byte[] GetBytes(this string str)
+               {
+                       byte[] bytes = new byte[str.Length * sizeof(char)];
+                       System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
+                       return bytes;
+               }
                public static bool IsWhiteSpaceOrNewLine (this char c)
                {
                        return c == '\t' || c == '\r' || c == '\n' || char.IsWhiteSpace (c);
index c74913300a43c2c8313647676ec43eef5672660a..5b6438c2168846fbd6b307dd4234f6edf67380e3 100644 (file)
@@ -1404,11 +1404,11 @@ namespace Crow
                        IFace.currentLQI.NewSlot = Slot;
                        Debug.WriteLine ("\t\t{0} => {1}",LastSlots,Slot);
                        #endif
-                       #if DESIGN_MODE
-                       if (IFace.GetType().Name == "DesignInterface"){
-                               Debug.WriteLine ("\t\t{2}: {0} => {1}",LastSlots,Slot,this.name);
-                       }
-                       #endif
+//                     #if DESIGN_MODE
+//                     if (IFace.GetType().Name == "DesignInterface"){
+//                             Debug.WriteLine ("\t\t{2}: {0} => {1}",LastSlots,Slot,this.name);
+//                     }
+//                     #endif
 
                        switch (layoutType) {
                        case LayoutingType.Width:
index 43f0819844b8d676a31aace5f2f61bab15a5ff58..9cedec81e766d1909bf897186e1573aa01475f53 100644 (file)
@@ -167,6 +167,17 @@ namespace Crow
                        this.RegisterForLayouting (LayoutingType.Sizing);
                        ChildrenCleared.Raise (this, new EventArgs ());
                }
+               public override void OnDataSourceChanged (object sender, DataSourceChangeEventArgs e)
+               {
+                       base.OnDataSourceChanged (this, e);
+
+                       childrenRWLock.EnterReadLock ();
+                       foreach (GraphicObject g in Children) {
+                               if (g.localDataSourceIsNull & g.localLogicalParentIsNull)
+                                       g.OnDataSourceChanged (g, e);   
+                       }
+                       childrenRWLock.ExitReadLock ();
+               }
 
                public void putWidgetOnTop(GraphicObject w)
                {
@@ -194,18 +205,7 @@ namespace Crow
                }
 
                #region GraphicObject overrides
-               public override void OnDataSourceChanged (object sender, DataSourceChangeEventArgs e)
-               {
-                       base.OnDataSourceChanged (this, e);
 
-                       childrenRWLock.EnterReadLock ();
-
-                       foreach (GraphicObject g in children)
-                               if (g.localDataSourceIsNull & g.localLogicalParentIsNull)
-                                       g.OnDataSourceChanged (g, e);
-                       
-                       childrenRWLock.ExitReadLock ();
-               }
                public override GraphicObject FindByName (string nameToFind)
                {
                        if (Name == nameToFind)
index d6392626c795c2390f9a31376d071f8f6c7dd994..c59abca8417279b924b7475afc01c08f362a9a24 100644 (file)
@@ -169,11 +169,11 @@ namespace Crow
                {
                        Picture pic;
                        if (path.EndsWith (".svg", true, System.Globalization.CultureInfo.InvariantCulture))
-                               pic = new SvgPicture ();
+                               pic = new SvgPicture (path);
                        else
-                               pic = new BmpPicture ();
+                               pic = new BmpPicture (path);
 
-                       pic.Load (path);
+                       pic.Load (IFace, path);
                        pic.Scaled = scaled;
                        pic.KeepProportions = keepProps;
 
index 584c180e53838ee8f2bfb9e07a79604750b5fc59..473fc313e4c11dd59c0fb37313a914e7745ca218 100644 (file)
@@ -90,7 +90,7 @@ namespace Crow
                        }
                }
                        
-               [XmlAttributeAttribute][DefaultValue(0)]
+               [DefaultValue(0)]
                public int TabOffset {
                        get { return tabOffset; }
                        set {
@@ -109,7 +109,7 @@ namespace Crow
                public Measure TabWidth {
                        get { return tview == null ? Measure.Fit : tview.TabWidth; }
                }
-               [XmlAttributeAttribute][DefaultValue(false)]
+               [DefaultValue(false)]
                public virtual bool IsSelected {
                        get { return isSelected; }
                        set {
index b11dfa69dd36a4667dfbc066819111a5c0f55e96..aa4dee2f768f6bdd0b9d9e4590ee715e964fdc0e 100644 (file)
@@ -183,23 +183,48 @@ namespace Crow.IML
                /// <param name="bd">Bd.</param>
                /// <param name="evt">passed as arg to prevent refetching it for the 3rd time</param>
                public void emitHandlerMethodAddition(EventBinding bd){
+
                        //fetch source instance with address for handler addition (as 1st arg of handler.add)
                        il.Emit (OpCodes.Ldloc_0);//push root
                        CompilerServices.emitGetInstance (il, bd.SourceNA);
 
+                       il.Emit (OpCodes.Ldloc_0);
+                       CompilerServices.emitGetInstance (il, bd.TargetNA);
+
+                       string[] membs = bd.TargetMember.Split ('.');
+                       for (int i = 0; i < membs.Length - 1; i++) {
+                               il.Emit (OpCodes.Dup);
+                               il.Emit (OpCodes.Ldstr, membs[i]);
+                               il.Emit (OpCodes.Call, CompilerServices.miGetMembIinfoWithRefx);
+                               il.Emit (OpCodes.Call, CompilerServices.miGetValWithRefx);
+                       }
+
                        //load handlerType of sourceEvent to create handler delegate (1st arg)
                        il.Emit (OpCodes.Ldtoken, bd.SourceEvent.EventHandlerType);
                        il.Emit (OpCodes.Call, CompilerServices.miGetTypeFromHandle);
-                       //load target the where the method is defined (2nd arg)
-                       il.Emit (OpCodes.Ldloc_0);
-                       CompilerServices.emitGetInstance (il, bd.TargetNA);
                        //load methodInfo (3rd arg)
-                       il.Emit (OpCodes.Ldstr, bd.TargetMember);
-
+                       il.Emit (OpCodes.Ldstr, membs[membs.Length-1]);
                        il.Emit (OpCodes.Callvirt, CompilerServices.miCreateDel);
-
                        il.Emit (OpCodes.Callvirt, bd.SourceEvent.AddMethod);//call add event
                }
-
+//             public void emitHandlerMethodAddition(EventBinding bd){
+//                     //fetch source instance with address for handler addition (as 1st arg of handler.add)
+//                     il.Emit (OpCodes.Ldloc_0);//push root
+//                     CompilerServices.emitGetInstance (il, bd.SourceNA);
+//
+//                     //load handlerType of sourceEvent to create handler delegate (1st arg)
+//                     il.Emit (OpCodes.Ldtoken, bd.SourceEvent.EventHandlerType);
+//                     il.Emit (OpCodes.Call, CompilerServices.miGetTypeFromHandle);
+//                     //load target the where the method is defined (2nd arg)
+//                     il.Emit (OpCodes.Ldloc_0);
+//                     CompilerServices.emitGetInstance (il, bd.TargetNA);
+//                     //load methodInfo (3rd arg)
+//                     il.Emit (OpCodes.Ldstr, bd.TargetMember);
+//
+//                     il.Emit (OpCodes.Callvirt, CompilerServices.miCreateDel);
+//
+//                     il.Emit (OpCodes.Callvirt, bd.SourceEvent.AddMethod);//call add event
+//             }
+//
        }
 }
\ No newline at end of file
index 49d4f5334c37beb2b8f0d1910484abf4b2575d6e..3eab819a417f665e03a622176fd8ad52457dfac2 100644 (file)
@@ -85,7 +85,7 @@ namespace Crow.IML
                /// <summary>
                /// Initializes a new instance of the Instantiator class.
                /// </summary>
-               public Instantiator (Interface _iface, string path) : this (_iface, Interface.GetStreamFromPath(path), path) {
+               public Instantiator (Interface _iface, string path) : this (_iface, _iface.GetStreamFromPath(path), path) {
                        
                }
                /// <summary>
@@ -335,7 +335,7 @@ namespace Crow.IML
                                                if (iface.Instantiators.ContainsKey (itemTemplatePath)) {
                                                        itemTemplateIds.Add (new string [] { "default", itemTemplatePath, "" });
                                                } else {
-                                                       using (Stream stream = Interface.GetStreamFromPath (itemTemplatePath)) {
+                                                       using (Stream stream = iface.GetStreamFromPath (itemTemplatePath)) {
                                                                //itemtemplate files may have multiple root nodes
                                                                XmlReaderSettings itrSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
                                                                using (XmlReader itr = XmlReader.Create (stream, itrSettings)) {                                                                        
index f17ac89515b54581b08b7eb32b385dd72490b1b2..00a952b0e440392d2d15cd0b840f197241c4ef67 100644 (file)
@@ -88,8 +88,6 @@ namespace Crow
                                }
                        }
 
-                       loadCursors ();
-
                        FontRenderingOptions = new FontOptions ();
                        FontRenderingOptions.Antialias = Antialias.Subpixel;
                        FontRenderingOptions.HintMetrics = HintMetrics.On;
@@ -103,6 +101,7 @@ namespace Crow
 
                public void Init () {
                        CurrentInterface = this;
+                       loadCursors ();
                        loadStyling ();
                        findAvailableTemplates ();
                        initTooltip ();
@@ -271,17 +270,17 @@ namespace Crow
 
                        }
                }
-               static void loadCursors(){
+               void loadCursors(){
                        //Load cursors
-                       XCursor.Cross = XCursorFile.Load("#Crow.Images.Icons.Cursors.cross").Cursors[0];
-                       XCursor.Default = XCursorFile.Load("#Crow.Images.Icons.Cursors.arrow").Cursors[0];
-                       XCursor.NW = XCursorFile.Load("#Crow.Images.Icons.Cursors.top_left_corner").Cursors[0];
-                       XCursor.NE = XCursorFile.Load("#Crow.Images.Icons.Cursors.top_right_corner").Cursors[0];
-                       XCursor.SW = XCursorFile.Load("#Crow.Images.Icons.Cursors.bottom_left_corner").Cursors[0];
-                       XCursor.SE = XCursorFile.Load("#Crow.Images.Icons.Cursors.bottom_right_corner").Cursors[0];
-                       XCursor.H = XCursorFile.Load("#Crow.Images.Icons.Cursors.sb_h_double_arrow").Cursors[0];
-                       XCursor.V = XCursorFile.Load("#Crow.Images.Icons.Cursors.sb_v_double_arrow").Cursors[0];
-                       XCursor.Text = XCursorFile.Load("#Crow.Images.Icons.Cursors.ibeam").Cursors[0];
+                       XCursor.Cross = XCursorFile.Load(this, "#Crow.Images.Icons.Cursors.cross").Cursors[0];
+                       XCursor.Default = XCursorFile.Load(this, "#Crow.Images.Icons.Cursors.arrow").Cursors[0];
+                       XCursor.NW = XCursorFile.Load(this, "#Crow.Images.Icons.Cursors.top_left_corner").Cursors[0];
+                       XCursor.NE = XCursorFile.Load(this, "#Crow.Images.Icons.Cursors.top_right_corner").Cursors[0];
+                       XCursor.SW = XCursorFile.Load(this, "#Crow.Images.Icons.Cursors.bottom_left_corner").Cursors[0];
+                       XCursor.SE = XCursorFile.Load(this, "#Crow.Images.Icons.Cursors.bottom_right_corner").Cursors[0];
+                       XCursor.H = XCursorFile.Load(this, "#Crow.Images.Icons.Cursors.sb_h_double_arrow").Cursors[0];
+                       XCursor.V = XCursorFile.Load(this, "#Crow.Images.Icons.Cursors.sb_v_double_arrow").Cursors[0];
+                       XCursor.Text = XCursorFile.Load(this, "#Crow.Images.Icons.Cursors.ibeam").Cursors[0];
                }
                #endregion
 
@@ -329,7 +328,28 @@ namespace Crow
                /// <returns>A file or resource stream</returns>
                /// <param name="path">This could be a normal file path, or an embedded ressource ID
                /// Resource ID's must be prefixed with '#' character</param>
-               public static Stream GetStreamFromPath (string path)
+               public virtual Stream GetStreamFromPath (string path)
+               {
+                       Stream stream = null;
+
+                       if (path.StartsWith ("#")) {
+                               string resId = path.Substring (1);
+                               //try/catch added to prevent nunit error
+                               try {
+                                       stream = System.Reflection.Assembly.GetEntryAssembly ().GetManifestResourceStream (resId);
+                               } catch{}
+                               if (stream == null)//try to find ressource in Crow assembly
+                                       stream = System.Reflection.Assembly.GetExecutingAssembly ().GetManifestResourceStream (resId);
+                               if (stream == null)
+                                       throw new Exception ("Resource not found: " + path);
+                       } else {
+                               if (!File.Exists (path))
+                                       throw new FileNotFoundException ("File not found: ", path);
+                               stream = new FileStream (path, FileMode.Open, FileAccess.Read);
+                       }
+                       return stream;
+               }
+               public static Stream StaticGetStreamFromPath (string path)
                {
                        Stream stream = null;
 
index fe7007c79d43a9d18bde12be95c2f66e32e2357e..3784780b812dbcae8def3491e482634dc238fc46 100644 (file)
@@ -87,7 +87,7 @@ namespace Crow
                /// <param name="path">image path, may be embedded</param>
                public Picture (string path)
                {
-                       Load (path);
+                       Path = path;
                }
                #endregion
 
@@ -96,7 +96,7 @@ namespace Crow
                /// load the image for rendering from the stream given as argument
                /// </summary>
                /// <param name="stream">picture stream</param>
-               public abstract void Load(string path);
+               public abstract void Load(Interface iface, string path);
                #endregion
 
                /// <summary>
@@ -117,11 +117,9 @@ namespace Crow
                        Picture _pic = null;
 
                        if (path.EndsWith (".svg", true, System.Globalization.CultureInfo.InvariantCulture)) 
-                               _pic = new SvgPicture ();
+                               _pic = new SvgPicture (path);
                        else 
-                               _pic = new BmpPicture ();
-
-                       _pic.Load (path);                       
+                               _pic = new BmpPicture (path);
 
                        return _pic;
                }
@@ -139,11 +137,9 @@ namespace Crow
                        Picture _pic = null;
 
                        if (path.EndsWith (".svg", true, System.Globalization.CultureInfo.InvariantCulture)) 
-                               _pic = new SvgPicture ();
+                               _pic = new SvgPicture (path);
                        else 
-                               _pic = new BmpPicture ();
-
-                       _pic.Load (path);                       
+                               _pic = new BmpPicture (path);
 
                        return _pic;
                }
index ce7fdedfc5a16237c7c44d0aabfcc41a7900d693..f676a4975d3796be9b280a4cca519415df4695eb 100644 (file)
@@ -51,7 +51,7 @@ namespace Crow
                {}
                #endregion
 
-               public override void Load (string path)
+               public override void Load (Interface iface, string path)
                {
                        Path = path;
                        if (sharedResources.ContainsKey (path)) {
@@ -60,7 +60,7 @@ namespace Crow
                                Dimensions = sp.Dims;
                                return;
                        }
-                       using (Stream stream = Interface.GetStreamFromPath (path)) {
+                       using (Stream stream = iface.GetStreamFromPath (path)) {
                                using (MemoryStream ms = new MemoryStream ()) {
                                        stream.CopyTo (ms);
 
index 627e2afdd473aa1cd70bc0580537b3a99fc3672c..1cca510e61beb62f3b1d38fa9db8ac00b7b0e813 100644 (file)
@@ -86,9 +86,9 @@ namespace Crow
                        return tmp;
                }
 
-               public static XCursorFile Load(string path)
+               public static XCursorFile Load(Interface iface, string path)
                {
-                       return loadFromStream (Interface.GetStreamFromPath (path));
+                       return loadFromStream (iface.GetStreamFromPath (path));
                }
 
                static XCursor imageLoad(BinaryReader sr)