gui-menu.xsh

GUI for multiple scripts execution

<?xml version="1.0" encoding="utf-8"?>
<xsharper xmlns="http://www.xsharper.com/schemas/1.0" id="gui_menu">
    <usage options="none" />
    <throw>This script must be executed only from another script</throw>
   
<sub id="gui-menu">
    <param name="title" />
    <param name="description" />
    <param name="scriptNames" required="true" />

<?_ Application.EnableVisualStyles();
   Application.SetCompatibleTextRenderingDefault(false);
   ScriptMenu f1=new ScriptMenu();
   f1.Context=c;
   f1.Title=c.GetString("title");
   f1.Description=c.GetString("description");
   foreach (string s in c.GetString("scriptNames").Split(';'))
       f1.Scripts.Add(c.Find<Script>(s,true));
   
   Application.Run(f1);
?>


<reference name="System.Windows.Forms" />
<reference name="System.Drawing" />
<?header using System;
   using System.Collections.Generic;
   using System.Diagnostics;
   using System.Drawing;
   using System.IO;
   using System.Threading;
   using System.Windows.Forms;
   using XSharper.Core;
   using System.Runtime.InteropServices;


   public partial class ScriptMenu : Form
   {
       private ManualResetEvent _running = new ManualResetEvent(false);
       private ManualResetEvent _stopEvent = new ManualResetEvent(false);
       private bool _closeOnStop = false;
       
       public ScriptContext Context;
       public List<Script> Scripts = new List<Script>();
       public string Description;
       public string Title;
       
       private List<Button> _buttons=new List<Button>();
       private Button btnExit;
       public ScriptMenu()
       {
           InitializeComponent();

       }
     
       [DllImport("User32.dll", CharSet = CharSet.Auto)]
       public static extern int SendMessage(IntPtr h, int msg, int wParam, int lParam);



       private void Form1_Load(object sender, EventArgs e)
       {
           this.Icon=Icon.ExtractAssociatedIcon(Process.GetCurrentProcess().MainModule.FileName);
           layButtons.RowCount = Scripts.Count + 2;
           for (int i = 0; i < Scripts.Count + 1; ++i)
           {

               Button b = new Button();
               b.Anchor = (AnchorStyles.Left | AnchorStyles.Right);
               b.Margin = new System.Windows.Forms.Padding(13, 3, 13, 3);
               b.Size = new System.Drawing.Size(260, 23);
               b.AutoSize=true;
               b.TabIndex = i;
               b.UseVisualStyleBackColor = true;
               if (i == Scripts.Count)
               {
                   b.DialogResult = DialogResult.Cancel;
                   CancelButton = b;
                   b.Text = "Exit";
                   b.Click += delegate { if (_running.WaitOne(0,false)) _stopEvent.Set(); else Close(); };
                   btnExit = b;
                   b.Anchor = (AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom);
                   b.Dock = DockStyle.Bottom;
               }
               else
               {
                   var script = Scripts[i];
                   b.Text = script.VersionInfo.Title;
                   b.Click += delegate { Run(script,b); };
                   _buttons.Add(b);
               }
               layButtons.Controls.Add(b, 0, i+1);
           }

           // Change font & tab stops
           reOut.LoadFonts();
           lblDescription.Text = Description;
           Text = Title+" - XSharper";            

           this.status.ResumeLayout(false);
           this.status.PerformLayout();
           this.tableLayoutPanel1.ResumeLayout(false);
           this.tableLayoutPanel1.PerformLayout();
           this.ResumeLayout(false);
           this.PerformLayout();

       }


       private void Run(Script script, Button b)
       {
           if (_running.WaitOne(0,false))
           {
               _stopEvent.Set();
               return;
           }
           Stopwatch sw = Stopwatch.StartNew();
           object ret = "";
           string oldText = btnExit.Text;
           string oldDir = Directory.GetCurrentDirectory();
           EventHandler<OutputEventArgs> oldOut=Context.Output;
           EventHandler<OperationProgressEventArgs> oldProgress=Context.Progress;
           try
           {
               _stopEvent.Reset();
               _running.Set();
               btnExit.Text = "&Cancel";
               btnExit.Update();
               reOut.Clear();
               foreach (var button in _buttons)
                   button.Enabled = false;

               Context.Output= OnOutput;
               Cursor = Cursors.WaitCursor;
               Context.Progress= OnProgress;
               

               statusText.Text = "Executing " + script.Id+"...";
               Context.Info.WriteLine("--- Executing " + script.Id +" ---");
               using (XS.ConsoleRedirector r=new XS.ConsoleRedirector(Context))
               {
                   Context.In=TextReader.Null;
                   ret = Context.ExecuteScript(script, null, CallIsolation.High);
               }
           }
           catch(Exception ex)
           {
               Context.WriteException(ex);
               statusText.Text = "Error: " + ex.Message;
               ret = -1;
           }
           finally
   {
               Context.Info.WriteLine("--- Completed in "+sw.Elapsed+" with return value="+ret+" ---");
               Directory.SetCurrentDirectory(oldDir);
               _running.Reset();
               reOut.ScrollToBottom();
               foreach (var button in _buttons)
                   button.Enabled = true;
               b.Focus();
               btnExit.Text = oldText;
               
               Context.Progress=oldProgress;
               Context.Output=oldOut;
                       
               statusText.Text = "Completed in " + sw.Elapsed + ", return value=" + ret;
               Cursor = Cursors.Arrow;
               if (_closeOnStop)
                   Close();
           }
       }

       private void OnProgress(object sender1, OperationProgressEventArgs e1)
       {
           Application.DoEvents();
           if (_stopEvent.WaitOne(0,false))
           {
               e1.Cancel = true;
               _stopEvent.Reset();
           }
       }
       
       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 before exit...";
               _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.status = new System.Windows.Forms.StatusStrip();
           this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
           this.reOut = new OutputRichTextBox();
           this.layButtons = new System.Windows.Forms.TableLayoutPanel();
           this.lblDescription = new System.Windows.Forms.Label();
           this.statusText = new System.Windows.Forms.ToolStripStatusLabel();
           this.status.SuspendLayout();
           this.tableLayoutPanel1.SuspendLayout();
           this.SuspendLayout();
           //
           // status
           //
           this.status.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
           this.statusText});
           this.status.Location = new System.Drawing.Point(0, 251);
           this.status.Name = "status";
           this.status.Size = new System.Drawing.Size(734, 22);
           this.status.TabIndex = 1;
           this.status.Text = "statusStrip1";
           //
           // tableLayoutPanel1
           //
           this.tableLayoutPanel1.ColumnCount = 2;
           this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 20F));
           this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 80F));
           this.tableLayoutPanel1.Controls.Add(this.reOut, 1, 1);
           this.tableLayoutPanel1.Controls.Add(this.layButtons, 0, 1);
           this.tableLayoutPanel1.Controls.Add(this.lblDescription, 0, 0);
           this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
           this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
           this.tableLayoutPanel1.Name = "tableLayoutPanel1";
           this.tableLayoutPanel1.RowCount = 2;
           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.Size = new System.Drawing.Size(734, 251);
           this.tableLayoutPanel1.TabIndex = 2;
           //
           // reOut
           //
           this.reOut.BackColor = System.Drawing.Color.Black;
           this.reOut.Dock = System.Windows.Forms.DockStyle.Fill;
           this.reOut.ForeColor = System.Drawing.Color.White;
           this.reOut.Location = new System.Drawing.Point(149, 26);
           this.reOut.MinimumSize = new System.Drawing.Size(600, 200);
           this.reOut.Name = "reOut";
           this.reOut.TabIndex = 100;
           this.reOut.Size = new System.Drawing.Size(500, 222);
           this.reOut.Text = "";
           this.reOut.ReadOnly = true;
           this.reOut.ShortcutsEnabled = true;
           
           //
           // layButtons
           //
           this.layButtons.AutoSize = true;
           this.layButtons.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
           this.layButtons.ColumnCount = 1;
           this.layButtons.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
           this.layButtons.Dock = System.Windows.Forms.DockStyle.Fill;
           this.layButtons.Location = new System.Drawing.Point(3, 26);
           this.layButtons.Name = "layButtons";
           this.layButtons.RowCount = 2;
           this.layButtons.RowStyles.Add(new System.Windows.Forms.RowStyle());
           this.layButtons.RowStyles.Add(new System.Windows.Forms.RowStyle());
           this.layButtons.Size = new System.Drawing.Size(140, 222);
           this.layButtons.TabIndex = 1;
           //
           // lblDescription
           //
           this.lblDescription.AutoSize = true;
           this.tableLayoutPanel1.SetColumnSpan(this.lblDescription, 2);
           this.lblDescription.Dock = System.Windows.Forms.DockStyle.Fill;
           this.lblDescription.Location = new System.Drawing.Point(13, 5);
           this.lblDescription.Margin = new System.Windows.Forms.Padding(13, 5, 13, 5);
           this.lblDescription.Name = "lblDescription";
           this.lblDescription.Size = new System.Drawing.Size(708, 13);
           this.lblDescription.TabIndex = 101;
           this.lblDescription.Text = "label1";
           this.lblDescription.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
           //
           // statusText
           //
           this.statusText.Name = "statusText";
           this.statusText.Size = new System.Drawing.Size(0, 17);
           //
           // Form1
           //
           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.Controls.Add(this.status);
           this.Name = "Form1";
           this.Text = "Form1";
           this.Load += new System.EventHandler(this.Form1_Load);
           this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);

       }

       #endregion

       private System.Windows.Forms.StatusStrip status;
       private System.Windows.Forms.TableLayoutPanel layButtons;
       private OutputRichTextBox reOut;
       private System.Windows.Forms.Label lblDescription;
       private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
       private System.Windows.Forms.ToolStripStatusLabel statusText;
   }      
   
   // 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>