<?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 requesting parameters in GUI." 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-param">
<param>${=$~myScript.IncludedScript}</param>
<param>${=.QuoteArgs(${args|=null})}</param>
</call>
<sub id="run-in-gui-param">
<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<XS.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;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text;
using XS=XSharper.Core;
using System.Runtime.InteropServices;
using System.Threading;
public class ExecutorForm : Form
{
private ManualResetEvent _running = new ManualResetEvent(false);
private ManualResetEvent _stopEvent = new ManualResetEvent(false);
private bool _closeOnStop = false;
public XS.ScriptContext Context;
public XS.Script Script;
public string Args;
public bool Autorun;
public ExecutorForm()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
KeyPreview = true;
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;
//
CustomPropertyCollection c = new CustomPropertyCollection();
string cat = null;
int catNo = 0;
foreach (XS.CommandLineParameter p in Script.Parameters)
{
if (string.IsNullOrEmpty(p.Var))
{
if (!string.IsNullOrEmpty(p.Value))
{
cat = p.Value;
catNo++;
}
continue;
}
if (cat == null) cat = "Parameters:";
c.Add(createProperty(p, Context, string.Concat((char)31, (char)(catNo + 32), cat)));
}
propertyGrid.SelectedObject = c;
propertyGrid.SetRatio(4);
propertyGrid.PropertyValueChanged += delegate { updateCommandLine(); };
edArgs.Validating += delegate(object snder, CancelEventArgs ex) { ex.Cancel = !updatePropertyGrid(); };
updatePropertyGrid();
if (Autorun)
BeginInvoke((MethodInvoker)delegate() { click(); });
}
private static CustomProperty createProperty(XS.CommandLineParameter p, XS.ScriptContext context, string category)
{
CustomProperty ret = new CustomProperty();
ret.DisplayName = p.GetDescription(context);
ret.Description = p.GetTransformedValue(context);
ret.Category = category;
string typename = context.TransformStr(p.TypeName, p.Transform);
if (p.Count == XS.CommandLineValueCount.Multiple)
ret.PropertyType = typeof(string[]);
else
ret.PropertyType = string.IsNullOrEmpty(typename) ? typeof(string) : (context.FindType(typename) ?? typeof(string));
if (p.Default != null)
ret.Value = ret.DefaultValue = XS.Utils.To(ret.PropertyType, context.Transform(p.Default, p.Transform));
else if (ret.PropertyType.IsValueType && !p.Required)
{
if (!(ret.PropertyType.IsGenericType && ret.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)))
ret.PropertyType = typeof (Nullable<>).MakeGenericType(ret.PropertyType);
}
if (ret.PropertyType == typeof(string))
{
List<string> possV = new List<string>();
bool regex = false;
if (!string.IsNullOrEmpty(p.Pattern) && p.Pattern.StartsWith("^(") && p.Pattern.EndsWith(")$"))
{
regex = true;
foreach (string s in p.Pattern.Substring(2, p.Pattern.Length - 4).Split('|'))
if (System.Text.RegularExpressions.Regex.IsMatch(s,"[^a-zA-Z0-9_]"))
regex=false;
if (regex)
foreach (string s in p.Pattern.Substring(2, p.Pattern.Length - 4).Split('|'))
{
string un = System.Text.RegularExpressions.Regex.Unescape(s);
possV.Add(un);
}
}
if (ret.DefaultValue != null)
possV.Add(XS.Utils.To<string>(ret.DefaultValue));
else if (!p.Required && !possV.Contains(null))
possV.Add(null);
if (p.Unspecified != null)
{
string v = XS.Utils.To<string>(context.Transform(p.Unspecified, p.Transform));
if (!possV.Contains(v))
possV.Add(v);
}
if (possV.Count != 0)
{
ret.StandardValues = possV.ToArray();
ret.OnlyStandardValues = (p.Count == XS.CommandLineValueCount.None || regex);
}
}
ret.Tag = p;
return ret;
}
bool updatePropertyGrid()
{
try
{
using (new XS.ScriptContextScope(Context))
{
XS.CommandLineParameters c = new XS.CommandLineParameters(Script.Parameters, Script.SwitchPrefixes, Script.UnknownSwitches);
c.Parse(Context, XS.Utils.SplitArgs(edArgs.Text), false);
c.ApplyDefaultValues(Context);
}
foreach (CustomProperty p in (CustomPropertyCollection)propertyGrid.SelectedObject)
{
XS.CommandLineParameter pp = (XS.CommandLineParameter)p.Tag;
if (Context.IsSet(pp.Var))
p.Value = XS.Utils.To(p.PropertyType, Context[pp.Var]);
else
p.Value = null;
}
propertyGrid.Refresh();
return true;
}
catch (Exception ee)
{
MessageBox.Show(ee.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
static bool isDefault(CustomProperty p)
{
XS.CommandLineParameter pp = (XS.CommandLineParameter)p.Tag;
return !(p.Value != null && (pp.Required || p.DefaultValue == null || !XS.Utils.To(p.PropertyType, p.Value).Equals(XS.Utils.To(p.PropertyType, p.DefaultValue))));
}
void updateCommandLine()
{
List<XS.ShellArg> args = new List<XS.ShellArg>();
CustomPropertyCollection coll=(CustomPropertyCollection)propertyGrid.SelectedObject;
for (int i=0;i<coll.Count;++i)
{
CustomProperty p =coll[i];
XS.CommandLineParameter pp = (XS.CommandLineParameter)p.Tag;
if (isDefault(p))
{
if (string.IsNullOrEmpty(pp.Switch))
{
for (int j=i+1;j<coll.Count;++j)
if (string.IsNullOrEmpty(((XS.CommandLineParameter)coll[j].Tag).Switch) && !isDefault(coll[j]))
{
XS.ShellArg a = new XS.ShellArg();
args.Add(a);
if (pp.Count != XS.CommandLineValueCount.None)
a.Value = p.Value;
a.Transform = XS.TransformRules.None;
}
}
}
else
{
XS.ShellArg a = new XS.ShellArg();
if (!string.IsNullOrEmpty(pp.Switch))
{
if (!string.IsNullOrEmpty(this.Script.SwitchPrefixes))
a.Switch = Script.SwitchPrefixes[0] + pp.Switch;
else
a.Switch = pp.Switch;
}
if (pp.Count != XS.CommandLineValueCount.None)
a.Value = p.Value;
a.Transform = XS.TransformRules.None;
args.Add(a);
}
}
edArgs.Text = XS.ShellArg.GetCommandLine(Context, args);
}
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<XS.OutputEventArgs> oldOut = Context.Output;
EventHandler<XS.OperationProgressEventArgs> oldProgress = Context.Progress;
try
{
_stopEvent.Reset();
_running.Set();
btnRun.Text = "&Cancel";
btnRun.Update();
reOut.Clear();
Context.MinOutputType = chkDebug.Checked ? XS.OutputType.Debug : XS.OutputType.Info;
Context.Output = OnOutput;
Cursor = Cursors.WaitCursor;
Context.Progress = delegate(object sender1, XS.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), XS.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, XS.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.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.label2 = new System.Windows.Forms.Label();
this.labelGrid = new System.Windows.Forms.Label();
this.propertyGrid = new PropertyGridEx();
this.btnRun = new System.Windows.Forms.Button();
this.chkDebug = new System.Windows.Forms.CheckBox();
this.lblDescription = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.edArgs = new System.Windows.Forms.TextBox();
this.reOut = new OutputRichTextBox();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
this.SuspendLayout();
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(0, 0);
this.splitContainer1.Name = "splitContainer1";
this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.tableLayoutPanel1);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.reOut);
this.splitContainer1.Size = new System.Drawing.Size(800, 550);
this.splitContainer1.SplitterDistance = 390;
this.splitContainer1.SplitterWidth = 5;
this.splitContainer1.TabIndex = 0;
//
// 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.labelGrid, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.propertyGrid, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.btnRun, 2, 1);
this.tableLayoutPanel1.Controls.Add(this.chkDebug, 2, 0);
this.tableLayoutPanel1.Controls.Add(this.lblDescription, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.label1, 0, 2);
this.tableLayoutPanel1.Controls.Add(this.edArgs, 1, 2);
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(System.Windows.Forms.SizeType.Percent, 80F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.Size = new System.Drawing.Size(800, 390);
this.tableLayoutPanel1.TabIndex = 0;
//
// 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;
//
// labelGrid
//
this.labelGrid.Location = new System.Drawing.Point(6, 26);
this.labelGrid.Name = "labelGrid";
this.labelGrid.Size = new System.Drawing.Size(100, 23);
this.labelGrid.TabIndex = 2;
this.labelGrid.Text = "&Parameters:";
this.labelGrid.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// propertyGrid
//
this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
this.propertyGrid.Location = new System.Drawing.Point(112, 29);
this.propertyGrid.Name = "propertyGrid";
this.propertyGrid.Size = new System.Drawing.Size(601, 329);
this.propertyGrid.TabIndex = 3;
this.propertyGrid.ToolbarVisible = false;
//
// btnRun
//
this.btnRun.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnRun.Dock = System.Windows.Forms.DockStyle.Top;
this.btnRun.Location = new System.Drawing.Point(719, 29);
this.btnRun.Name = "btnRun";
this.btnRun.Size = new System.Drawing.Size(75, 21);
this.btnRun.TabIndex = 7;
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(719, 6);
this.chkDebug.Name = "chkDebug";
this.chkDebug.Size = new System.Drawing.Size(75, 17);
this.chkDebug.TabIndex = 6;
this.chkDebug.Text = "&Debug";
this.chkDebug.UseVisualStyleBackColor = true;
//
// 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(601, 23);
this.lblDescription.TabIndex = 1;
this.lblDescription.Text = "...";
this.lblDescription.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// label1
//
this.label1.Location = new System.Drawing.Point(6, 361);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(95, 26);
this.label1.TabIndex = 4;
this.label1.Text = "&Command line:";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// edArgs
//
this.edArgs.Dock = System.Windows.Forms.DockStyle.Fill;
this.edArgs.Location = new System.Drawing.Point(112, 364);
this.edArgs.Name = "edArgs";
this.edArgs.Size = new System.Drawing.Size(601, 20);
this.edArgs.TabIndex = 5;
//
// reOut
//
this.reOut.BackColor = System.Drawing.Color.Black;
this.reOut.Dock = System.Windows.Forms.DockStyle.Fill;
this.reOut.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.reOut.ForeColor = System.Drawing.Color.White;
this.reOut.Location = new System.Drawing.Point(0, 0);
this.reOut.Name = "reOut";
this.reOut.ReadOnly = true;
this.reOut.RightToLeft = System.Windows.Forms.RightToLeft.No;
this.reOut.Size = new System.Drawing.Size(800, 155);
this.reOut.TabIndex = 0;
this.reOut.Text = "";
//
// ExecutorForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 550);
this.Controls.Add(this.splitContainer1);
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.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel2.ResumeLayout(false);
this.splitContainer1.ResumeLayout(false);
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 labelGrid;
private System.Windows.Forms.Label lblDescription;
private PropertyGridEx propertyGrid;
private System.Windows.Forms.SplitContainer splitContainer1;
}
// 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(XS.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 XS.OutputType.Debug: this.SelectionColor = Color.Cyan; break;
case XS.OutputType.Error: this.SelectionColor = Color.Yellow; break;
case XS.OutputType.Info: this.SelectionColor = Color.LightGreen; break;
case XS.OutputType.Bold: this.SelectionColor = Color.White; break;
default: this.SelectionColor = Color.LightGray; break;
}
if (otype == XS.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();
}
}
#region -- Extended property grid --
public class PropertyGridEx : PropertyGrid
{
private const int WM_KEYDOWN = 0x100;
private const int TAB = 9;
private bool _setEvent;
private double _ratio;
private Control _propertyGridView;
public PropertyGridEx()
{
}
protected override bool ProcessKeyPreview(ref Message m)
{
if (m.Msg == WM_KEYDOWN && m.WParam.ToInt32() == TAB)
{
bool forward = (ModifierKeys & Keys.Shift) == 0;
if (moveSelectedGridItem(forward))
return true;
}
return ProcessKeyEventArgs(ref m);
}
protected override bool ProcessTabKey(bool forward)
{
moveSelectedGridItem(forward);
return true;
}
public void SetRatio(double ratio)
{
_ratio = ratio;
_propertyGridView = Controls[2];
if (!_setEvent)
{
_setEvent = true;
_propertyGridView.VisibleChanged += delegate { setRatio(); };
_propertyGridView.SizeChanged += delegate { setRatio(); };
}
setRatio();
}
private void setRatio()
{
try
{
if (_propertyGridView != null)
{
Type propertyGridViewType = _propertyGridView.GetType();
System.Reflection.FieldInfo fldLabelRatio = propertyGridViewType.GetField("labelRatio", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
if (fldLabelRatio != null)
{
fldLabelRatio.SetValue(_propertyGridView, _ratio);
Invalidate();
}
}
}
catch
{
}
}
private bool moveSelectedGridItem(bool forward)
{
if (SelectedGridItem == null || SelectedGridItem.Parent == null)
return false;
GridItem p = SelectedGridItem.Parent.Parent;
GridItemCollection allItems = SelectedGridItem.Parent.GridItems;
int currentIndex = -1;
for (int i = 0; i < allItems.Count; i++)
if (allItems[i] == SelectedGridItem)
{
currentIndex = i;
break;
}
if (forward)
{
if (currentIndex >= 0 && currentIndex < allItems.Count - 1)
{
SelectedGridItem = allItems[currentIndex + 1];
return false;
}
if (currentIndex == allItems.Count - 1 && p != null)
{
GridItemCollection pitems = p.GridItems;
for (int j = 0; j < pitems.Count - 1; j++)
if (pitems[j] == SelectedGridItem.Parent)
{
SelectedGridItem = pitems[j + 1].GridItems[0];
return false;
}
Parent.SelectNextControl(this, forward, true, false, true);
return false;
}
}
else
{
if (currentIndex == 0 && p != null)
{
GridItemCollection pitems = p.GridItems;
for (int j = 1; j < pitems.Count; j++)
if (pitems[j] == SelectedGridItem.Parent)
{
SelectedGridItem = pitems[j - 1].GridItems[pitems[j - 1].GridItems.Count - 1];
return false;
}
Parent.SelectNextControl(this, forward, true, false, true);
}
else if (currentIndex >= 1 && currentIndex < allItems.Count)
{
SelectedGridItem = allItems[currentIndex - 1];
return true;
}
}
return true;
}
}
public class CustomPropertyCollection : List<CustomProperty>, ICustomTypeDescriptor
{
public AttributeCollection GetAttributes() { return TypeDescriptor.GetAttributes(this, true); }
public string GetClassName() { return TypeDescriptor.GetClassName(this, true); }
public string GetComponentName() { return TypeDescriptor.GetComponentName(this, true); }
public TypeConverter GetConverter() { return new PropertySorter(ConvertAll(delegate(CustomProperty x) { return x.DisplayName; }).ToArray()); }
public EventDescriptor GetDefaultEvent() { return TypeDescriptor.GetDefaultEvent(this, true); }
public PropertyDescriptor GetDefaultProperty() { return TypeDescriptor.GetDefaultProperty(this, true); }
public object GetEditor(System.Type editorBaseType) { return TypeDescriptor.GetEditor(this, editorBaseType, true); }
public EventDescriptorCollection GetEvents() { return TypeDescriptor.GetEvents(this, true); }
public EventDescriptorCollection GetEvents(System.Attribute[] attributes) { return TypeDescriptor.GetEvents(this, attributes, true); }
public PropertyDescriptorCollection GetProperties() { return GetProperties(null); }
public object GetPropertyOwner(PropertyDescriptor pd) { return this; }
public PropertyDescriptorCollection GetProperties(System.Attribute[] attributes)
{
return new PropertyDescriptorCollection(ConvertAll(delegate(CustomProperty x) { return x.CreateDescriptor(); }).ToArray());
}
#region -- private classes --
class PropertySorter : ExpandableObjectConverter
{
private readonly string[] _names;
public PropertySorter(string[] names) { _names = names; }
public override bool GetPropertiesSupported(ITypeDescriptorContext context) { return true; }
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
return TypeDescriptor.GetProperties(value, attributes).Sort(_names);
}
}
#endregion
}
public class CustomProperty
{
public object Tag ;
public string DisplayName ;
public bool IsReadOnly ;
public object Value ;
public string Description ;
public string Category ;
public bool Parenthesize ;
public bool IsPassword ;
public bool IsPercentage ;
public Type PropertyType ;
public object DefaultValue ;
public object[] StandardValues ;
public bool OnlyStandardValues ;
public PropertyDescriptor CreateDescriptor()
{
List<Attribute> attrs = new List<Attribute>();
if (IsPassword) attrs.Add(new PasswordPropertyTextAttribute(true));
if (Parenthesize) attrs.Add(new ParenthesizePropertyNameAttribute(true));
FlagsAttribute[] a = (FlagsAttribute[])PropertyType.GetCustomAttributes(typeof(FlagsAttribute), true);
if (PropertyType != null && a.Length > 0) attrs.Add(new EditorAttribute(typeof(FlagsEditor), typeof(UITypeEditor)));
if (IsPercentage) attrs.Add(new TypeConverterAttribute(typeof(OpacityConverter)));
if (PropertyType == typeof(string)) attrs.Add(new TypeConverterAttribute(typeof(List2PropertyConverter)));
if (DefaultValue == null)
attrs.Add(new DefaultValueAttribute(DefaultValue));
return new CustomPropertyDescriptor(this, attrs.ToArray());
}
#region == private adapter classes==
public class CustomPropertyDescriptor : PropertyDescriptor
{
private CustomProperty _property;
public CustomPropertyDescriptor(CustomProperty myProperty, Attribute[] attrs)
: base(myProperty.DisplayName, attrs)
{
_property = myProperty;
}
public CustomProperty Property { get { return _property; } }
public override Type ComponentType { get { return GetType(); } }
public override object GetValue(object component) { return Property.Value; }
public override bool IsReadOnly { get { return Property.IsReadOnly; } }
public override Type PropertyType { get { return Property.PropertyType; } }
public override string Description { get { return Property.Description; } }
public override string Category { get { return Property.Category; } }
public override string DisplayName { get { return Property.DisplayName; } }
public override bool IsBrowsable { get { return false; } }
public override bool CanResetValue(object component)
{
return (Property.DefaultValue != null);
}
public override void ResetValue(object component)
{
Property.Value = Property.DefaultValue;
OnValueChanged(component, EventArgs.Empty);
}
public override void SetValue(object component, object value)
{
Property.Value = value;
OnValueChanged(component, EventArgs.Empty);
}
public override bool ShouldSerializeValue(object component)
{
object oValue = Property.Value;
if ((Property.DefaultValue != null) && (oValue != null))
return !oValue.Equals(Property.DefaultValue);
return false;
}
}
internal class List2PropertyConverter : StringConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
CustomPropertyDescriptor cp = context.PropertyDescriptor as CustomPropertyDescriptor;
return (cp != null && cp.Property.StandardValues != null);
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
CustomPropertyDescriptor cp = context.PropertyDescriptor as CustomPropertyDescriptor;
return (cp != null && cp.Property.OnlyStandardValues);
}
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
CustomPropertyDescriptor cp = context.PropertyDescriptor as CustomPropertyDescriptor;
return new StandardValuesCollection(cp.Property.StandardValues);
}
}
internal class FlagsEditor : UITypeEditor
{
class ComboItem
{
public ComboItem(string displayName, ulong value, string tooltip)
{
DisplayName = displayName;
Value = value;
Tooltip = tooltip;
}
public ulong Value;
public string Tooltip;
public string DisplayName;
public override string ToString() { return DisplayName; }
}
private System.Windows.Forms.Design.IWindowsFormsEditorService _edSvc = null;
private CheckedListBox _clb;
private ToolTip _tooltipControl;
private bool _handleLostfocus = false;
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (context == null || context.Instance == null || provider == null)
return value;
_edSvc = (System.Windows.Forms.Design.IWindowsFormsEditorService)provider.GetService(typeof(System.Windows.Forms.Design.IWindowsFormsEditorService));
if (_edSvc == null)
return value;
// Create a CheckedListBox and populate it with all the enum values
_clb = new CheckedListBox();
_clb.Sorted = false;
_clb.BorderStyle = BorderStyle.FixedSingle;
_clb.CheckOnClick = true;
_clb.MouseDown += OnMouseDown;
_clb.MouseMove += OnMouseMoved;
_clb.ItemCheck += OnItemCheck;
_tooltipControl = new ToolTip();
_tooltipControl.ShowAlways = true;
ulong intEdited = (ulong)Convert.ChangeType(value ?? 0, typeof(ulong));
foreach (string name in Enum.GetNames(context.PropertyDescriptor.PropertyType))
{
object enumVal = Enum.Parse(context.PropertyDescriptor.PropertyType, name);
ulong enumNumValue = (ulong)Convert.ChangeType(enumVal, typeof(ulong));
System.Reflection.FieldInfo fi = context.PropertyDescriptor.PropertyType.GetField(name);
DescriptionAttribute[] attrs = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
string tooltip = attrs.Length > 0 ? attrs[0].Description : string.Empty;
CheckState cs = CheckState.Indeterminate;
if ((intEdited & enumNumValue) == 0)
cs = CheckState.Unchecked;
else if ((intEdited & enumNumValue) == enumNumValue)
cs = CheckState.Checked;
_clb.Items.Add(new ComboItem(name, enumNumValue, tooltip), cs);
}
if (_clb.Items.Count > 4)
{
_clb.Height = _clb.ItemHeight * Math.Min(_clb.Items.Count + 1, 10);
}
// Show our CheckedListbox as a DropDownControl.
// This methods returns only when the dropdowncontrol is closed
_edSvc.DropDownControl(_clb);
// Get the sum of all checked flags
ulong result = GetResult(-1, CheckState.Indeterminate);
// return the right enum value corresponding to the result
return Enum.ToObject(context.PropertyDescriptor.PropertyType, result);
}
ulong GetResult(int nv, CheckState cs)
{
ulong result = 0;
for (int i = 0; i < _clb.Items.Count; ++i)
{
CheckState c = (i == nv) ? cs : _clb.GetItemCheckState(i);
if (c == CheckState.Checked)
result |= ((ComboItem)_clb.Items[i]).Value;
}
return result;
}
private volatile int _loopCheck = 0;
private void OnItemCheck(object sender, ItemCheckEventArgs e)
{
if (_loopCheck++ == 0)
{
ulong result = GetResult(e.Index, e.NewValue);
for (int i = 0; i < _clb.Items.Count; ++i)
{
ulong v = ((ComboItem)_clb.Items[i]).Value;
CheckState cs = CheckState.Indeterminate;
if ((result & v) == 0)
cs = CheckState.Unchecked;
else if ((result & v) == v)
cs = CheckState.Checked;
_clb.SetItemCheckState(i, cs);
}
}
_loopCheck--;
}
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) { return UITypeEditorEditStyle.DropDown; }
private void OnMouseDown(object sender, MouseEventArgs e)
{
if (!_handleLostfocus && _clb.ClientRectangle.Contains(_clb.PointToClient(new Point(e.X, e.Y))))
{
_clb.LostFocus += ValueChanged;
_handleLostfocus = true;
}
}
private void OnMouseMoved(object sender, MouseEventArgs e)
{
int index = _clb.IndexFromPoint(e.X, e.Y);
if (index >= 0)
_tooltipControl.SetToolTip(_clb, ((ComboItem)_clb.Items[index]).Tooltip);
}
private void ValueChanged(object sender, EventArgs e)
{
if (_edSvc != null)
_edSvc.CloseDropDown();
}
}
#endregion
}
#endregion
?>
</sub>
</xsharper>