Files
ayanova7/source/Plugins/AyaNova.PlugIn.AyaScript/AyaScript.cs
2018-06-29 19:47:36 +00:00

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
}