gui-console.xsh

GUI for single script execution

<?xml version="1.0" encoding="utf-8"?>
<xsharper xmlns="http://www.xsharper.com/schemas/1.0" unknownSwitches="true">
    <versionInfo title="gui-console" value="Run XSharper script in a normal Window." Version="0.1.0.0" Copyright="(C) 2009 DeltaX Inc." />
    <usage options="ifNoArguments default" />

    <param switch="run" required="false" value="Run immediately after loading" count="none" />
    <param name="filename" required="true" value="Script to execute" description="filename.xsh" />
    <param name="args" required="false" value="Command line arguments for the script" count="multiple" description="arguments" last="true" />

    <include id="myScript" from="${filename}" dynamic="true" />
    <call subId="run-in-gui-console">
        <param>${=$~myScript.IncludedScript}</param>
        <param>${=.QuoteArgs(${args|=null})}</param>
    </call>

<sub id="run-in-gui-console">
    <param name="script" required="true" />
    <param name="scriptArgs" required="true" />

    <?_ Application.EnableVisualStyles();
       Application.SetCompatibleTextRenderingDefault(false);
       ExecutorForm f1=new ExecutorForm();
       f1.Context=c;
       if (c["script"] is XS.Script)
           f1.Script=(XS.Script)c["script"];
       else
           f1.Script=c.Find<Script>(c.GetString("script"),true);

       f1.Args=c.GetString("scriptArgs");
       f1.Autorun=c.GetBool("run",false);
       Application.Run(f1);
   ?>

<reference name="System.Windows.Forms" />
<reference name="System.Drawing" />

<?header using System.Windows.Forms;
   using System.Collections.Generic;
   using System.ComponentModel;
   using System.Data;
   using System.Diagnostics;
   using System.Drawing;
   using System.IO;
   using System.Text;
   using System.Windows.Forms;
   using XSharper.Core;
   using System.Xml;
   using System.Runtime.InteropServices;
   using System.Text.RegularExpressions;  
   using System.Threading;

   
   public  class ExecutorForm : Form
   {
       private ManualResetEvent _running = new ManualResetEvent(false);
       private ManualResetEvent _stopEvent = new ManualResetEvent(false);
       private bool _closeOnStop = false;

       public ScriptContext Context;
       public Script Script;
       public string Args;
       public bool Autorun;
       

       public ExecutorForm()
       {
           InitializeComponent();
       }

       
       private void Form1_Load(object sender, EventArgs e)
       {
           this.Icon=Icon.ExtractAssociatedIcon(Process.GetCurrentProcess().MainModule.FileName);
       
           // Change font & tab stops
           reOut.LoadFonts();            
           
           
           lblDescription.Text = Script.VersionInfo.GenerateInfo(Context,true);

           string title=Context.TransformStr(Script.VersionInfo.Title,Script.VersionInfo.Transform);
           if (string.IsNullOrEmpty(title))
               title=Script.Id;
           if (string.IsNullOrEmpty(title))
               title=Script.Location;
           if (string.IsNullOrEmpty(title))
               Text = "XSharper";
           else
               Text = title+" - XSharper";
           edArgs.Text=Args ?? "";
           edArgs.SelectionStart=0;
           edArgs.SelectionLength=0;
           if (Autorun)
               BeginInvoke((MethodInvoker)delegate() { click(); });
       }

       void btnRun_Click(object sender, EventArgs e)
       {
           click();
       }
       
       void click()
       {
           if (_running.WaitOne(0,false))
           {
               _stopEvent.Set();
               return;
           }
           Stopwatch sw = Stopwatch.StartNew();
           object ret = null;
           string oldText = btnRun.Text;
           string oldDir = Directory.GetCurrentDirectory();
           EventHandler<OutputEventArgs> oldOut=Context.Output;
           EventHandler<OperationProgressEventArgs> oldProgress=Context.Progress;
           
           try
           {
               _stopEvent.Reset();
               _running.Set();
               btnRun.Text = "&Cancel";
               btnRun.Update();
               reOut.Clear();
               
               Context.MinOutputType = chkDebug.Checked ? OutputType.Debug : OutputType.Info;
               Context.Output= OnOutput;
               Cursor = Cursors.WaitCursor;

               Context.Progress= delegate(object sender1, OperationProgressEventArgs e1)
               {
                   Application.DoEvents();
                   if (_stopEvent.WaitOne(0,false))
                   {
                       e1.Cancel = true;
                       _stopEvent.Reset();                      
                   }
               };
               
               using (XS.ConsoleRedirector r=new XS.ConsoleRedirector(Context))
               {
                   Context.In=TextReader.Null;
                   ret = Context.ExecuteScript(Script, XS.Utils.SplitArgs(edArgs.Text), CallIsolation.High);
               }
           }
           catch(Exception ex)
           {
               Context.WriteException(ex);
               ret = -1;
           }
           
               
           Directory.SetCurrentDirectory(oldDir);
           _running.Reset();
           btnRun.Text = oldText;
           Context.Info.WriteLine("--- Completed in "+sw.Elapsed+" with return value="+ret+" ---");
           reOut.ScrollToBottom();
           Context.Progress=oldProgress;
           Context.Output=oldOut;
           Cursor = Cursors.Arrow;
           Context.Progress = null;
           Context.Output = null;
           if (_closeOnStop)
               Close();
       }

       

       private void OnOutput(object sender1, OutputEventArgs e1)
       {
           reOut.Output(e1.OutputType,e1.Text);
       }
       private void Form1_FormClosing(object sender, FormClosingEventArgs e)
       {
           if (_running.WaitOne(0,false))
           {
               Text = "Cancelling script...";
               _stopEvent.Set();
               _closeOnStop = true;
               e.Cancel = true;
               
               return;
           }
       }
       

       
       /// <summary>
       /// Required designer variable.
       /// </summary>
       private System.ComponentModel.IContainer components = null;

       /// <summary>
       /// Clean up any resources being used.
       /// </summary>
       /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
       protected override void Dispose(bool disposing)
       {
           if (disposing && (components != null))
           {
               components.Dispose();
           }
           base.Dispose(disposing);
       }

       #region Windows Form Designer generated code

       /// <summary>
       /// Required method for Designer support - do not modify
       /// the contents of this method with the code editor.
       /// </summary>
       private void InitializeComponent()
       {
           this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
           this.label2 = new System.Windows.Forms.Label();
           this.reOut = new OutputRichTextBox();
           this.edArgs = new System.Windows.Forms.TextBox();
           this.btnRun = new System.Windows.Forms.Button();
           this.chkDebug = new System.Windows.Forms.CheckBox();
           this.label1 = new System.Windows.Forms.Label();
           this.lblDescription = new System.Windows.Forms.Label();
           this.tableLayoutPanel1.SuspendLayout();
           this.SuspendLayout();
           //
           // tableLayoutPanel1
           //
           this.tableLayoutPanel1.ColumnCount = 3;
           this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
           this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
           this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
           this.tableLayoutPanel1.Controls.Add(this.label2, 0, 0);
           this.tableLayoutPanel1.Controls.Add(this.reOut, 0, 2);
           this.tableLayoutPanel1.Controls.Add(this.edArgs, 1, 1);
           this.tableLayoutPanel1.Controls.Add(this.btnRun, 2, 1);
           this.tableLayoutPanel1.Controls.Add(this.chkDebug, 2, 0);
           this.tableLayoutPanel1.Controls.Add(this.label1, 0, 1);
           this.tableLayoutPanel1.Controls.Add(this.lblDescription, 1, 0);
           this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
           this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
           this.tableLayoutPanel1.Name = "tableLayoutPanel1";
           this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(3);
           this.tableLayoutPanel1.RightToLeft = System.Windows.Forms.RightToLeft.No;
           this.tableLayoutPanel1.RowCount = 3;
           this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
           this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
           this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
           this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
           this.tableLayoutPanel1.Size = new System.Drawing.Size(979, 501);
           this.tableLayoutPanel1.TabIndex = 1;
           //
           // label2
           //
           this.label2.Location = new System.Drawing.Point(6, 3);
           this.label2.Name = "label2";
           this.label2.Size = new System.Drawing.Size(100, 23);
           this.label2.TabIndex = 0;
           this.label2.Text = "Script description:";
           this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
           //
           // lblDescription
           //
           this.lblDescription.AccessibleRole = System.Windows.Forms.AccessibleRole.Document;
           this.lblDescription.AutoSize = true;
           this.lblDescription.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
           this.lblDescription.Dock = System.Windows.Forms.DockStyle.Fill;
           this.lblDescription.Location = new System.Drawing.Point(112, 3);
           this.lblDescription.Name = "lblDescription";
           this.lblDescription.Size = new System.Drawing.Size(780, 23);
           this.lblDescription.TabIndex = 1;
           this.lblDescription.Text = "...";
           this.lblDescription.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;

           //
           // label1
           //
           this.label1.Location = new System.Drawing.Point(6, 26);
           this.label1.Name = "label1";
           this.label1.Size = new System.Drawing.Size(95, 26);
           this.label1.TabIndex = 2;
           this.label1.Text = "&Arguments:";
           this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
           
           //
           // edArgs
           //
           this.edArgs.Dock = System.Windows.Forms.DockStyle.Fill;
           this.edArgs.Location = new System.Drawing.Point(112, 29);
           this.edArgs.Name = "edArgs";
           this.edArgs.Size = new System.Drawing.Size(780, 20);
           this.edArgs.TabIndex = 3;
           //
           // btnRun
           //
           this.btnRun.DialogResult = System.Windows.Forms.DialogResult.OK;
           this.btnRun.Dock = System.Windows.Forms.DockStyle.Fill;
           this.btnRun.Location = new System.Drawing.Point(898, 29);
           this.btnRun.Name = "btnRun";
           this.btnRun.Size = new System.Drawing.Size(75, 21);
           this.btnRun.TabIndex = 4;
           this.btnRun.Text = "&Run";
           this.btnRun.UseVisualStyleBackColor = true;
           this.btnRun.Click += new System.EventHandler(this.btnRun_Click);
           
           //
           // chkDebug
           //
           this.chkDebug.AutoSize = true;
           this.chkDebug.Dock = System.Windows.Forms.DockStyle.Bottom;
           this.chkDebug.Location = new System.Drawing.Point(898, 6);
           this.chkDebug.Name = "chkDebug";
           this.chkDebug.Size = new System.Drawing.Size(75, 17);
           this.chkDebug.TabIndex = 5;
           this.chkDebug.Text = "&Debug";
           this.chkDebug.UseVisualStyleBackColor = true;
           
           //
           // reOut
           //
           this.reOut.BackColor = System.Drawing.Color.Black;
           this.tableLayoutPanel1.SetColumnSpan(this.reOut, 3);
           this.reOut.Dock = System.Windows.Forms.DockStyle.Fill;
           this.reOut.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
           this.reOut.ForeColor = System.Drawing.Color.White;
           this.reOut.Location = new System.Drawing.Point(6, 56);
           this.reOut.Name = "reOut";
           this.reOut.ReadOnly = true;
           this.reOut.RightToLeft = System.Windows.Forms.RightToLeft.No;
           this.reOut.Size = new System.Drawing.Size(967, 439);
           this.reOut.TabIndex = 6;
           this.reOut.Text = "";
           this.reOut.ShortcutsEnabled = true;            
           
           
           //
           // ExecutorForm
           //
           this.AcceptButton = this.btnRun;
           this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
           this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
           this.ClientSize = new System.Drawing.Size(800, 500);
           this.Controls.Add(this.tableLayoutPanel1);
           this.Name = "ExecutorForm";
           this.Text = " Sample Script Executor";
           this.Load += new System.EventHandler(this.Form1_Load);
           this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
           this.tableLayoutPanel1.ResumeLayout(false);
           this.tableLayoutPanel1.PerformLayout();
           this.ResumeLayout(false);

       }

       #endregion

       private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
       private OutputRichTextBox reOut;
       private System.Windows.Forms.Button btnRun;
       private System.Windows.Forms.CheckBox chkDebug;
       private System.Windows.Forms.Label label2;
       private System.Windows.Forms.TextBox edArgs;
       private System.Windows.Forms.Label label1;
       private System.Windows.Forms.Label lblDescription;

   }
   
   // Extended richedit box, that supports different fonts and backspace character
   public  class OutputRichTextBox : RichTextBox
   {
       private Font _font,_fontBold;

       [DllImport("User32.dll", CharSet = CharSet.Auto)]
       private static extern int SendMessage(IntPtr h, int msg, int wParam, int lParam);
       
       private Font createFont(bool bold)
       {
           Font f=new Font("Consolas", 9, bold?FontStyle.Bold:FontStyle.Regular);
           if (f.Name != "Consolas")
               f = new Font("Courier New", 9, bold?FontStyle.Bold:FontStyle.Regular);
           return f;
       }
       
       public void LoadFonts()
       {
           _font=createFont(false);
           _fontBold=createFont(true);
           this.Font = _font;
       }
       public void ScrollToBottom()
       {
           SendMessage(this.Handle, 0x115, 7, 0);
       }
       
       public void Output(OutputType otype, string text)
       {        
           this.Select(this.TextLength,0);
           StringBuilder sb=new StringBuilder();
           foreach (char ch in text)
           {
               if (ch==(char)8)
               {
                   if (sb.Length>0)
                       this.AppendText(sb.ToString());
                   while (this.TextLength>0)
                   {
                       this.Select(this.TextLength-1,1);                  
                       string s=this.SelectedText;
                       if (s=="\n" || s=="\r" || s=="")
                       {
                           this.Select(this.TextLength,0);
                           break;
                       }
                       this.Select(this.TextLength-1,1);                  
                       this.ReadOnly=false;
                       this.SelectedText=string.Empty;
                       this.ReadOnly=true;
                   }
                   sb.Length=0;
               }
               else
               {
                   if (sb.Length==0)
                   {
                       switch (otype)
                       {
                           case OutputType.Debug:  this.SelectionColor = Color.Cyan;   break;
                           case OutputType.Error:  this.SelectionColor = Color.Yellow; break;
                           case OutputType.Info:   this.SelectionColor = Color.LightGreen; break;
                           case OutputType.Bold:   this.SelectionColor = Color.White; break;
                           default:                this.SelectionColor = Color.LightGray; break;
                       }
                       if (otype==OutputType.Bold)
                       {
                           if (this.SelectionFont.Bold!=true)
                               this.SelectionFont=_fontBold;
                       }
                       else if (this.SelectionFont.Bold!=false)
                           this.SelectionFont=_font;
                   }
                   sb.Append(ch);
                   if (sb.Length>5000)
                   {
                       this.AppendText(sb.ToString());
                       sb.Length=0;
                   }
                       
               }
           }
           this.AppendText(sb.ToString());

           ScrollToBottom();
           Application.DoEvents();
       }
   }
   
   
?>
</sub>
</xsharper>