514 lines
17 KiB
C#
514 lines
17 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using AyaNova.PlugIn;
|
|
using GZTW.AyaNova.BLL;
|
|
using System.ComponentModel;
|
|
using System.Windows.Forms;
|
|
using System.Reflection;
|
|
using System.Data;
|
|
using System.Text.RegularExpressions;
|
|
using System.IO;
|
|
using CSScriptLibrary;
|
|
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace AyaNova.PlugIn.AyaScript
|
|
{
|
|
public class AyaScript : IAyaNovaPlugin
|
|
{
|
|
|
|
//Holds the image resources from AyaNova
|
|
//so we can display the correct icons in our plugin
|
|
System.Resources.ResourceManager resman = null;
|
|
|
|
//Holds the current logged in user's localized text
|
|
//lookup object
|
|
LocalizedTextTable LocaleText = null;
|
|
|
|
#region IAyaNovaPlugin Members
|
|
|
|
#region interface properties
|
|
public string PluginName
|
|
{
|
|
get { return "AyaScript"; }
|
|
}
|
|
|
|
public string PluginVersion
|
|
{
|
|
get { return "7.5"; }
|
|
}
|
|
|
|
public string About
|
|
{
|
|
get
|
|
{
|
|
return "AyaNova AyaScript plugin\r\n" +
|
|
"Built " + AyaNova.PlugIn.AyaScript.Timestamp.BuildAt.ToString() + "\r\n" +
|
|
"Copyright 2009-2018 Ground Zero Tech-Works Inc.";
|
|
}
|
|
}
|
|
|
|
public Guid PluginID
|
|
{
|
|
get { return new Guid("{C8FAE0E3-542E-4143-9708-1C3BDA2508B2}"); }
|
|
}
|
|
|
|
public System.Drawing.Image PluginSmallIcon
|
|
{
|
|
get { return Resource.Script16; }
|
|
}
|
|
|
|
public System.Drawing.Image PluginLargeIcon
|
|
{
|
|
get { return Resource.Script24; }
|
|
}
|
|
|
|
public System.Resources.ResourceManager AyaNovaResourceManager
|
|
{
|
|
set { resman = value; }
|
|
get { return resman; }
|
|
}
|
|
#endregion interface properties
|
|
|
|
#region Initialization and Close
|
|
public bool Initialize(Version AyaNovaVersion, LocalizedTextTable localizedText)
|
|
{
|
|
LocaleText = localizedText;
|
|
if (!Util.LoadScripts())
|
|
{
|
|
MessageBox.Show("AyaScript plugin disabled due to error loading scripts!");
|
|
return false;
|
|
}
|
|
|
|
Util.AYS = this;
|
|
return true;
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
Util.AYS=null;
|
|
}
|
|
#endregion Initialization and close
|
|
|
|
#region ShowMenu?
|
|
public bool SingleObjectMenuShow(RootObjectTypes objectType)
|
|
{
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool MultipleObjectsMenuShow(RootObjectTypes objectType)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
#endregion show menu?
|
|
|
|
#region Menu options
|
|
public List<AyaNovaPluginMenuItem> SingleObjectMenuOptions(RootObjectTypes objectType, object ayaNovaObject)
|
|
{
|
|
List<AyaNovaPluginMenuItem> list = new List<AyaNovaPluginMenuItem>();
|
|
list.Add(new AyaNovaPluginMenuItem("AyaScriptEditor", "AyaScript Editor", Resource.Script24, Resource.Script16));
|
|
foreach (Util.ScriptItem i in Util.ScriptList)
|
|
{
|
|
if(i.Show(true,objectType))
|
|
list.Add(new AyaNovaPluginMenuItem(i.ScriptID.ToString(), i.ScriptName, null, null));
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
public List<AyaNovaPluginMenuItem> MultipleObjectsMenuOptions(RootObjectTypes objectType)
|
|
{
|
|
List<AyaNovaPluginMenuItem> list = new List<AyaNovaPluginMenuItem>();
|
|
list.Add(new AyaNovaPluginMenuItem("AyaScriptEditor", "AyaScript Editor", Resource.Script24, Resource.Script16));
|
|
foreach (Util.ScriptItem i in Util.ScriptList)
|
|
{
|
|
if (i.Show(false, objectType))
|
|
list.Add(new AyaNovaPluginMenuItem(i.ScriptID.ToString(), i.ScriptName, null, null));
|
|
}
|
|
return list;
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
#region Menu Commands
|
|
|
|
#region LIST OBJECT COMMAND
|
|
/// <summary>
|
|
/// LIST OBJECT
|
|
/// </summary>
|
|
/// <param name="commandKey"></param>
|
|
/// <param name="objectType"></param>
|
|
/// <param name="objectIDList"></param>
|
|
/// <param name="listObject"></param>
|
|
/// <returns></returns>
|
|
public bool CommandSelectedForList(string commandKey, RootObjectTypes objectType, List<Guid> objectIDList, object listObject)
|
|
{
|
|
if (commandKey == "AyaScriptEditor")
|
|
{
|
|
ScriptDesigner sd = new ScriptDesigner();
|
|
sd.ShowDialog();
|
|
sd.Dispose();
|
|
return true;
|
|
}
|
|
Util.ExecuteScript(new Guid(commandKey), true, objectType, listObject, objectIDList);
|
|
|
|
return true;
|
|
}
|
|
|
|
#endregion list object command
|
|
|
|
#region SINGLE OBJECT COMMAND
|
|
/// <summary>
|
|
/// SINGLE OBJECT
|
|
/// </summary>
|
|
/// <param name="commandKey"></param>
|
|
/// <param name="objectType"></param>
|
|
/// <param name="ayaNovaObject"></param>
|
|
public void CommandSelectedForSingleObject(string commandKey, RootObjectTypes objectType, object ayaNovaObject)
|
|
{
|
|
if (commandKey == "AyaScriptEditor")
|
|
{
|
|
ScriptDesigner sd = new ScriptDesigner();
|
|
sd.ShowDialog();
|
|
sd.Dispose();
|
|
return;
|
|
}
|
|
Util.ExecuteScript(new Guid(commandKey),false, objectType, ayaNovaObject, new List<Guid>());
|
|
}
|
|
#endregion single object command
|
|
|
|
#endregion menu commands
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
|
|
public class Util
|
|
{
|
|
public static AyaScript AYS { get; set; }
|
|
|
|
#region Regular expressions
|
|
//Name: MyTestCode
|
|
public static Regex rxName = new Regex(
|
|
"//Name:\\s*([^\\r\\n]*)",
|
|
RegexOptions.IgnoreCase
|
|
| RegexOptions.Multiline
|
|
| RegexOptions.Compiled
|
|
);
|
|
|
|
//ShowInMenuFor: List / SingleObject / Everywhere / MainOnly
|
|
public static Regex rxShowInMenuFor = new Regex(
|
|
"//ShowInMenuFor:\\s*([^\\r\\n]*)",
|
|
RegexOptions.IgnoreCase
|
|
| RegexOptions.Multiline
|
|
| RegexOptions.Compiled
|
|
);
|
|
|
|
|
|
//HandlesAyaNovaTypes: Client, HeadOffice, Unit
|
|
public static Regex rxHandlesAyaNovaTypes = new Regex(
|
|
"//HandlesAyaNovaTypes:\\s*([^\\r\\n]*)",
|
|
RegexOptions.IgnoreCase
|
|
| RegexOptions.Multiline
|
|
| RegexOptions.Compiled
|
|
);
|
|
|
|
// //UniqueID: Guid
|
|
// public static Regex rxUniqueID = new Regex(
|
|
// "//UniqueID:\\s*([^\\r\\n]*)",
|
|
//RegexOptions.IgnoreCase
|
|
//| RegexOptions.Multiline
|
|
//| RegexOptions.Compiled
|
|
//);
|
|
|
|
|
|
#endregion regex
|
|
|
|
#region script store
|
|
private static List<ScriptItem> mScriptList;
|
|
public static List<ScriptItem> ScriptList
|
|
{
|
|
get
|
|
{
|
|
if (mScriptList == null) mScriptList = new List<ScriptItem>();
|
|
return mScriptList;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private static string dbFile = "";
|
|
public static bool LoadScripts()
|
|
{
|
|
//check for db file in same folder this plugin loaded from and if not found create one
|
|
dbFile = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\AyaScripts.xml";
|
|
DataTable dt = new DataTable("Scripts");
|
|
|
|
#region Load or create scripts file
|
|
if (File.Exists(dbFile))
|
|
{
|
|
try
|
|
{
|
|
dt.ReadXml(dbFile);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show("AyaScript plugin failed to load scripts from " + dbFile + ", error: \r\n" + ex.Message);
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//create it
|
|
try
|
|
{
|
|
//setup the columns
|
|
dt.Columns.Add("script", typeof(string));
|
|
dt.WriteXml(dbFile, XmlWriteMode.WriteSchema);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show("AyaScript plugin failed to initialize and write new dataset to " + dbFile + ", error: \r\n" + ex.Message);
|
|
return false;
|
|
}
|
|
}
|
|
#endregion load or create scripts file
|
|
|
|
#region parse scripts
|
|
ScriptList.Clear();
|
|
foreach (DataRow dr in dt.Rows)
|
|
ScriptList.Add(new ScriptItem(dr[0].ToString()));
|
|
|
|
#endregion parse
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Persist scripts back to file
|
|
/// </summary>
|
|
public static void WriteScripts()
|
|
{
|
|
DataTable dt = new DataTable("Scripts");
|
|
dt.Columns.Add("script", typeof(string));
|
|
foreach (ScriptItem i in ScriptList)
|
|
{
|
|
DataRow dr = dt.NewRow();
|
|
dr[0] = i.ScriptText;
|
|
dt.Rows.Add(dr);
|
|
}
|
|
|
|
dt.WriteXml(dbFile, XmlWriteMode.WriteSchema);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save a script into the script cache, if a script with the same id exists previously, it's replaced
|
|
/// </summary>
|
|
/// <param name="sScript"></param>
|
|
public static void SaveScript(string sScript, Guid ID)
|
|
{
|
|
ScriptItem si = new ScriptItem(sScript);
|
|
si.ScriptID = ID;
|
|
//remove if present already since it's been updated
|
|
DeleteScript(si.ScriptID);
|
|
ScriptList.Add(si);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Remove script from cache if present
|
|
/// </summary>
|
|
/// <param name="scriptID">Guid of script</param>
|
|
public static void DeleteScript(Guid scriptID)
|
|
{
|
|
for(int x=0;x<ScriptList.Count();x++)
|
|
{
|
|
if(ScriptList[x].ScriptID==scriptID)
|
|
{
|
|
ScriptList.RemoveAt(x);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public static string GetScript(string sName)
|
|
{
|
|
foreach (ScriptItem si in ScriptList)
|
|
{
|
|
if(si.ScriptName.Equals(sName, StringComparison.CurrentCultureIgnoreCase))
|
|
return si.ScriptText;
|
|
}
|
|
return "Script \"" + sName + "\" not found in cache.";
|
|
}
|
|
|
|
public static string GetScript(Guid ID)
|
|
{
|
|
foreach (ScriptItem si in ScriptList)
|
|
{
|
|
if (si.ScriptID==ID)
|
|
return si.ScriptText;
|
|
}
|
|
return "Script \"" + ID.ToString() + "\" not found in cache.";
|
|
}
|
|
|
|
|
|
#endregion script store
|
|
|
|
#region Script execution
|
|
|
|
|
|
/// <summary>
|
|
/// Execute script
|
|
/// </summary>
|
|
/// <param name="ID"></param>
|
|
public static void ExecuteScript(Guid ID, bool IsList, RootObjectTypes objectType, Object ayaNovaObject, List<Guid> objectIDList)
|
|
{
|
|
string s = "";
|
|
foreach (ScriptItem si in ScriptList)
|
|
{
|
|
if (si.ScriptID == ID)
|
|
{
|
|
s=si.ScriptText;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!s.Contains("AyaScriptMain"))
|
|
{
|
|
MessageBox.Show("Main method AyaScriptMain not found, nothing to execute!");
|
|
return;
|
|
}
|
|
|
|
//for some reason cs-script throws a null reference exception when a null
|
|
//parameter is passed in
|
|
if (ayaNovaObject == null) ayaNovaObject = DBNull.Value;
|
|
|
|
try
|
|
{
|
|
var script = new AsmHelper(CSScript.LoadMethod(AddUsings(s)));
|
|
script.Invoke("*.AyaScriptMain", IsList, objectType, ayaNovaObject, objectIDList);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show("Error running script:\r\n----- Exception message -----\r\n" + ex.Message);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Add the most common using statements
|
|
/// if not already present
|
|
/// </summary>
|
|
/// <param name="sScript"></param>
|
|
/// <returns></returns>
|
|
private static string AddUsings(string sScript)
|
|
{
|
|
System.Text.StringBuilder sb = new StringBuilder();
|
|
|
|
//if (!sScript.Contains("using System;")) sb.Append("using System;\r\n");
|
|
if (!sScript.Contains("using System.Collections.Generic;")) sb.Append("using System.Collections.Generic;\r\n");
|
|
if (!sScript.Contains("using System.Data;")) sb.Append("using System.Data;\r\n");
|
|
if (!sScript.Contains("using System.Drawing;")) sb.Append("using System.Drawing;\r\n");
|
|
if (!sScript.Contains("using System.Text;")) sb.Append("using System.Text;\r\n");
|
|
if (!sScript.Contains("using System.Windows.Forms;")) sb.Append("using System.Windows.Forms;\r\n");
|
|
if (!sScript.Contains("using GZTW.AyaNova.BLL;")) sb.Append("using GZTW.AyaNova.BLL;\r\n");
|
|
if (!sScript.Contains("using AyaNova.PlugIn.AyaScript;")) sb.Append("using AyaNova.PlugIn.AyaScript;\r\n");
|
|
|
|
sb.Append(sScript);
|
|
return sb.ToString();
|
|
}
|
|
#endregion script execution
|
|
|
|
#region parse
|
|
[Serializable]
|
|
public class ScriptItem
|
|
{
|
|
public ScriptItem(string Script)
|
|
{
|
|
//parse and set properties
|
|
ScriptText = Script;
|
|
|
|
//Name
|
|
ScriptName = Util.rxName.Match(Script).Groups[1].Value;
|
|
if (string.IsNullOrEmpty(ScriptName))
|
|
ScriptName = "Script " + System.DateTime.Now.ToString();
|
|
|
|
//Show in menu for
|
|
ScriptShowInMenuFor = Util.rxShowInMenuFor.Match(Script).Groups[1].Value;
|
|
if (string.IsNullOrEmpty(ScriptShowInMenuFor))
|
|
ScriptShowInMenuFor = "Everywhere";
|
|
|
|
//ID
|
|
ScriptID = Guid.NewGuid();
|
|
|
|
|
|
//Object types
|
|
ScriptHandlesTypes = new List<RootObjectTypes>();
|
|
List<string> lsRootObjects = Util.rxHandlesAyaNovaTypes.Match(Script).Groups[1].Value.Replace(" ", "").Split(',').ToList<string>();
|
|
if (lsRootObjects.Count == 0)
|
|
lsRootObjects = new List<string>(new string[] { "Client" });
|
|
|
|
foreach (string s in lsRootObjects)
|
|
{
|
|
try
|
|
{
|
|
ScriptHandlesTypes.Add((RootObjectTypes)Enum.Parse(typeof(RootObjectTypes), s, true));
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
}
|
|
|
|
public bool Show(bool bFromSingle, RootObjectTypes oType)
|
|
{
|
|
if(ScriptShowInMenuFor.Equals("Everywhere", StringComparison.CurrentCultureIgnoreCase)) return true;
|
|
if(ScriptShowInMenuFor.Equals("Main menu only", StringComparison.CurrentCultureIgnoreCase) && oType== RootObjectTypes.Nothing) return true;
|
|
|
|
if(bFromSingle)
|
|
{
|
|
if(!ScriptShowInMenuFor.Equals("Single AyaNova object", StringComparison.CurrentCultureIgnoreCase))
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if (!ScriptShowInMenuFor.Equals("List of AyaNova objects", StringComparison.CurrentCultureIgnoreCase))
|
|
return false;
|
|
}
|
|
|
|
if (ScriptHandlesTypes.Contains(oType))
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
public string ScriptText { get; set; }
|
|
public string ScriptName { get; set; }
|
|
public Guid ScriptID { get; set; }
|
|
public string ScriptShowInMenuFor { get; set; }
|
|
public List<RootObjectTypes> ScriptHandlesTypes { get; set; }
|
|
|
|
|
|
}
|
|
#endregion parse
|
|
|
|
}//bottom of util class
|
|
|
|
|
|
|
|
|
|
|
|
}
|