--- /dev/null
+using System;\r
+using OpenMetaverse;\r
+using System.Windows.Forms;\r
+\r
+namespace Radegast\r
+{\r
+ public class AvatarProfileAction : ContextAction\r
+ {\r
+ public AvatarProfileAction(RadegastInstance inst)\r
+ : base(inst)\r
+ {\r
+ Label = "Profile";\r
+ ContextType = typeof(Avatar);\r
+ }\r
+ public override bool IsEnabled(object target)\r
+ {\r
+ return true;\r
+ }\r
+ public override void OnInvoke(object sender, EventArgs e, object target)\r
+ {\r
+ UUID id = ToUUID(target);\r
+ if (id == UUID.Zero) id = ToUUID(sender);\r
+ if (id == UUID.Zero)\r
+ {\r
+ DebugLog("cannot find avatar" + target);\r
+ return;\r
+ }\r
+ (new frmProfile(instance, instance.getAvatarName(id), id)).Show();\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+using System;\r
+using System.Drawing;\r
+using System.Windows.Forms;\r
+using OpenMetaverse;\r
+\r
+namespace Radegast\r
+{\r
+ public class ContextAction : IContextAction\r
+ {\r
+ public Type ContextType;\r
+ public virtual string Label { get; set; }\r
+ public EventHandler Handler;\r
+ protected RadegastInstance instance;\r
+ public bool Enabled { get; set; }\r
+ public virtual object DeRef(object o)\r
+ {\r
+ if (o is Control)\r
+ {\r
+ Control control = (Control) o;\r
+ if (control.Tag != null) return control.Tag;\r
+ if (!string.IsNullOrEmpty(control.Text)) return control.Text;\r
+ if (!string.IsNullOrEmpty(control.Name)) return control.Name;\r
+ }\r
+ else if (o is ListViewItem)\r
+ {\r
+ ListViewItem control = (ListViewItem) o;\r
+ if (control.Tag != null) return control.Tag;\r
+ if (!string.IsNullOrEmpty(control.Name)) return control.Name;\r
+ if (!string.IsNullOrEmpty(control.Text)) return control.Text;\r
+ }\r
+ return o;\r
+ }\r
+ protected ContextActionsManager ContextActionManager\r
+ {\r
+ get { return Instance.ContextActionManager; }\r
+ }\r
+ public virtual RadegastInstance Instance\r
+ {\r
+ get\r
+ {\r
+ return instance;\r
+ }\r
+ set\r
+ {\r
+ if (instance == value)\r
+ return;\r
+ instance = value;\r
+ }\r
+ }\r
+\r
+ protected virtual GridClient Client\r
+ {\r
+ get\r
+ {\r
+ return Instance.Client;\r
+ }\r
+ }\r
+\r
+ public ContextAction(RadegastInstance inst)\r
+ {\r
+ Enabled = true;\r
+ instance = inst;\r
+ }\r
+\r
+ public virtual bool IsEnabled(object target)\r
+ {\r
+ return Enabled && Contributes(target);\r
+ }\r
+\r
+ public virtual ToolStripItem GetToolItem(object target)\r
+ {\r
+ return new ToolStripMenuItem(\r
+ LabelFor(target), (Image) null,\r
+ (sender, e) => TryCatch(() => OnInvoke(sender, e, target)))\r
+ {\r
+ Enabled = IsEnabled(target),\r
+ };\r
+ }\r
+\r
+ protected void TryCatch(MethodInvoker func)\r
+ {\r
+ try\r
+ {\r
+ func();\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ DebugLog("Exception: " + e);\r
+ }\r
+ }\r
+\r
+\r
+ public virtual string LabelFor(object target)\r
+ {\r
+ return Label;\r
+ }\r
+\r
+ public virtual Button GetButton(object target)\r
+ {\r
+ Button button = new Button { Text = LabelFor(target), Enabled = IsEnabled(target) };\r
+ button.Click += (sender, e) => TryCatch(() => OnInvoke(sender, e, target));\r
+ return button;\r
+ }\r
+\r
+ public virtual bool TypeContributes(Type o)\r
+ {\r
+ return ContextType.IsAssignableFrom(o);\r
+ }\r
+\r
+ public virtual bool Contributes(Object o)\r
+ {\r
+ if (o==null) return false;\r
+ object oo = DeRef(o);\r
+ return (oo != o && Contributes(oo)) || TypeContributes(o.GetType());\r
+ }\r
+\r
+ public virtual void OnInvoke(object sender, EventArgs e, object target)\r
+ {\r
+ if (Handler != null) Handler(DeRef(target ?? sender), e);\r
+ }\r
+\r
+ public virtual void IContextAction(RadegastInstance instance)\r
+ {\r
+ Instance = instance;\r
+ }\r
+\r
+ public virtual void Dispose()\r
+ { \r
+ }\r
+\r
+ public Primitive ToPrimitive(object target)\r
+ {\r
+ Primitive thePrim = ((target is Primitive) ? (Primitive)target : null);\r
+ if (thePrim != null) return thePrim;\r
+ object oo = DeRef(target);\r
+ if (oo != target)\r
+ {\r
+ thePrim = ToAvatar(oo);\r
+ if (thePrim != null) return thePrim;\r
+ }\r
+ UUID uuid = ((target is UUID) ? (UUID)target : UUID.Zero);\r
+ if (uuid != UUID.Zero)\r
+ thePrim = Client.Network.CurrentSim.ObjectsPrimitives.Find(prim => (prim.ID == uuid));\r
+ return thePrim;\r
+ }\r
+\r
+ public Avatar ToAvatar(object target)\r
+ {\r
+ Primitive thePrim = ((target is Primitive) ? (Primitive)target : null);\r
+ if (thePrim != null) return (Avatar)thePrim;\r
+ object oo = DeRef(target);\r
+ if (oo != target)\r
+ {\r
+ thePrim = ToAvatar(oo);\r
+ if (thePrim != null) return (Avatar)thePrim;\r
+ }\r
+ UUID uuid = ((target is UUID) ? (UUID)target : UUID.Zero);\r
+ if (uuid != UUID.Zero)\r
+ thePrim = Client.Network.CurrentSim.ObjectsAvatars.Find(prim => (prim.ID == uuid));\r
+ return (Avatar)thePrim;\r
+ }\r
+\r
+ public UUID ToUUID(object target)\r
+ {\r
+ UUID uuid = ((target is UUID) ? (UUID)target : UUID.Zero);\r
+ if (target is FriendInfo)\r
+ {\r
+ return ((FriendInfo) target).UUID;\r
+ }\r
+ if (target is GroupMember)\r
+ {\r
+ return ((GroupMember)target).ID;\r
+ }\r
+ if (uuid != UUID.Zero) return uuid;\r
+ object oo = DeRef(target);\r
+ if (oo != target)\r
+ {\r
+ uuid = ToUUID(oo);\r
+ if (uuid != UUID.Zero) return uuid;\r
+ }\r
+ string str = ((target is string) ? (string)target : null);\r
+ if (string.IsNullOrEmpty(str))\r
+ {\r
+ if (UUID.TryParse(str, out uuid))\r
+ {\r
+ return uuid;\r
+ }\r
+ }\r
+ Primitive prim = ToPrimitive(target);\r
+ if (prim != null) return prim.ID;\r
+ Avatar avatar = ToAvatar(target);\r
+ if (avatar != null) return avatar.ID;\r
+ return uuid;\r
+ }\r
+\r
+ public void DebugLog(string s)\r
+ {\r
+ instance.TabConsole.DisplayNotificationInChat(string.Format("ContextAction {0}: {1}", Label, s));\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using System.Drawing;\r
+using System.Windows.Forms;\r
+using OpenMetaverse;\r
+\r
+namespace Radegast\r
+{\r
+ public class ContextActionsManager : IDisposable\r
+ {\r
+ List<IContextAction> contextEventHandlers = new List<IContextAction>();\r
+ private readonly RadegastInstance instance;\r
+ public ContextActionsManager(RadegastInstance instance)\r
+ {\r
+ this.instance = instance;\r
+ }\r
+\r
+ /// <summary>\r
+ /// AddContextMenu(typeof(Object), "Clueless Object!",\r
+ /// (obj, hand)\r
+ /// => Console.WriteLine("I am an Object!: {0} {1} {2}", obj, hand, obj.GetType()));\r
+ /// </summary>\r
+ /// <param name="libomvType"></param>\r
+ /// <param name="label"></param>\r
+ /// <param name="handler"></param>\r
+ public void AddContextMenu(Type libomvType, String label, EventHandler handler)\r
+ {\r
+ AddContextMenu(new ContextAction(instance)\r
+ {\r
+ Label = label,\r
+ Handler = handler,\r
+ ContextType = libomvType\r
+ });\r
+ }\r
+\r
+ public void AddContextMenu(IContextAction handler)\r
+ {\r
+ lock (contextEventHandlers)\r
+ {\r
+ handler.IContextAction(instance);\r
+ contextEventHandlers.Add(handler);\r
+ }\r
+ }\r
+\r
+ internal void AddContributions(ToolStripDropDown strip, Object o)\r
+ {\r
+ AddContributions(strip, o.GetType(), o);\r
+ }\r
+\r
+ public void AddContributions(ToolStripDropDown strip, List<ToolStripItem> items)\r
+ {\r
+ if (items==null || items.Count == 0) return; \r
+ foreach(var i in strip.Items)\r
+ {\r
+ if (i is ToolStripItem)\r
+ {\r
+ ToolStripItem item = (ToolStripItem) i;\r
+ if (string.IsNullOrEmpty(item.Text)) continue;\r
+ ToolStripItem dup = items.Find((o)=> !string.IsNullOrEmpty(o.Text) && o.Text.ToLower() == item.Text.ToLower());\r
+ if (dup!=null)\r
+ items.Remove(dup);\r
+ }\r
+ }\r
+ if (items.Count == 0) return; \r
+ strip.Items.AddRange(items.ToArray());\r
+ strip.Closing += ((sender, args) => items.ForEach((o) => strip.Items.Remove(o)));\r
+ }\r
+\r
+ internal void AddContributions(ToolStripDropDown strip, Type type, Object obj, params Control[] controls)\r
+ {\r
+ List<ToolStripItem> items = new List<ToolStripItem>();\r
+ GleanContributions(strip, type, obj, controls);\r
+ if (strip.Parent != null) GleanContributions(strip, type, obj, strip.Parent);\r
+ foreach (IContextAction i in contextEventHandlers)\r
+ {\r
+ if (!i.TypeContributes(type) && !i.Contributes(obj)) continue;\r
+ items.Add(i.GetToolItem(obj));\r
+ }\r
+ items.Sort(CompareItems);\r
+ if (strip.Items.Count > 0) items.Insert(0, new ToolStripSeparator());\r
+ //if (!instance.advancedDebugging) return;\r
+ if (items.Count > 1) items.Add(new ToolStripSeparator());\r
+ string newVariable = obj.GetType() == type\r
+ ? type.Name\r
+ : string.Format("{0} -> {1}", obj.GetType().Name, type.Name);\r
+ items.Add(new ToolStripMenuItem(newVariable, null,\r
+ (sender, e) =>\r
+ instance.TabConsole.DisplayNotificationInChat(\r
+ string.Format(" sender={0}\ntarget={1}", ToString(sender), ToString(obj)))\r
+\r
+ )\r
+ {\r
+ Enabled = true,\r
+ ToolTipText = "" + obj\r
+ });\r
+\r
+ AddContributions(strip, items);\r
+ }\r
+\r
+ private string ToString(object sender)\r
+ {\r
+ string t = sender.GetType().Name + ":";\r
+ if (sender is Control)\r
+ {\r
+ Control control = (Control)sender;\r
+ return string.Format("{0}{1} {2} {3}", t, control.Text, control.Name, ToString(control.Tag));\r
+ }\r
+ if (sender is ListViewItem)\r
+ {\r
+ ListViewItem control = (ListViewItem)sender;\r
+ return string.Format("{0}{1} {2} {3}", t, control.Text, control.Name, ToString(control.Tag));\r
+ }\r
+ return t + sender;\r
+ }\r
+\r
+ public void GleanContributions(ToolStripDropDown strip, Type type, Object obj, params Control[] controls)\r
+ {\r
+ List<ToolStripItem> items = new List<ToolStripItem>();\r
+ foreach (Control control in controls) GleanContributions(items, type, control, obj); \r
+ if (obj is Control)\r
+ {\r
+ Control control1 = (Control) obj;\r
+ GleanContributions(items, type, control1.Parent, obj);\r
+ }\r
+ if (items.Count == 0) return;\r
+ items.Sort(CompareItems);\r
+ if (strip.Items.Count > 0) items.Insert(0, new ToolStripSeparator());\r
+ AddContributions(strip, items);\r
+ }\r
+\r
+ public void GleanContributions(List<ToolStripItem> items, Type type, Control control, Object obj)\r
+ {\r
+ if (control == null) return;\r
+ if (control is Button)\r
+ {\r
+ Button button = (Button) control;\r
+ string newVariable = obj.GetType() == type\r
+ ? type.Name\r
+ : string.Format("{0} -> {1}", obj.GetType().Name, type.Name);\r
+ items.Add(new ToolStripMenuItem(button.Text, null,\r
+ (sender, e) =>\r
+ {\r
+ button.PerformClick();\r
+ Logger.DebugLog(String.Format("Button: {0} {1} {2} {3}",\r
+ newVariable, e, sender, obj));\r
+ })\r
+ {\r
+ Enabled = button.Enabled,\r
+ ToolTipText = "" + obj\r
+ });\r
+ return;\r
+ }\r
+ foreach (object v in control.Controls)\r
+ GleanContributions(items, type, (Control) v, obj);\r
+ }\r
+\r
+ static int CompareItems(ToolStripItem i1, ToolStripItem i2)\r
+ {\r
+ if (i1 == i2) return 0;\r
+ if (i1 is ToolStripSeparator)\r
+ return (i2 is ToolStripSeparator) ? 0 : -1;\r
+ int i = string.Compare(i1.Text, i2.Text);\r
+ return i == 0 ? i1.GetHashCode().CompareTo(i2.GetHashCode()) : i;\r
+ }\r
+\r
+ public void Dispose()\r
+ {\r
+ lock (contextEventHandlers)\r
+ {\r
+ foreach (IContextAction handler in contextEventHandlers)\r
+ {\r
+ try\r
+ {\r
+ handler.Dispose();\r
+ }\r
+ catch (Exception) { }\r
+ }\r
+ contextEventHandlers.Clear();\r
+ }\r
+\r
+ }\r
+ public void LoadType(Type type)\r
+ {\r
+ if (typeof(IContextAction).IsAssignableFrom(type) && type != typeof(ContextAction))\r
+ {\r
+ try\r
+ {\r
+ var c = type.GetConstructor(new Type[] { typeof(RadegastInstance) });\r
+ if (c != null)\r
+ {\r
+ IContextAction plug = (IContextAction)c.Invoke(new object[] { instance });\r
+ AddContextMenu(plug);\r
+ return;\r
+ }\r
+ c = type.GetConstructor(Type.EmptyTypes);\r
+ if (c != null)\r
+ {\r
+ IContextAction plug = (IContextAction)c.Invoke(new object[0]);\r
+ AddContextMenu(plug);\r
+ return;\r
+ }\r
+ }\r
+ catch (Exception ex)\r
+ {\r
+ Logger.Log("ERROR in Radegast Command: " + type + " because " + ex.Message + " " + ex.StackTrace,\r
+ Helpers.LogLevel.Debug);\r
+ throw ex;\r
+ }\r
+ return;\r
+ }\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+using System;\r
+using OpenMetaverse;\r
+\r
+namespace Radegast\r
+{\r
+ public class DeRezObjectAction : ContextAction\r
+ {\r
+ public DeRezObjectAction(RadegastInstance inst)\r
+ : base(inst)\r
+ {\r
+ Label = "DeRez..";\r
+ ContextType = typeof(Primitive);\r
+ }\r
+\r
+ public override void OnInvoke(object sender, EventArgs e, object target)\r
+ {\r
+ Primitive thePrim = ToPrimitive(target) ?? ToPrimitive(sender);\r
+ if (thePrim == null)\r
+ {\r
+ DebugLog("Not found prim: " + sender + " " +target);\r
+ return;\r
+ }\r
+ DebugLog("Found prim: " + thePrim);\r
+ Client.Inventory.RequestDeRezToInventory(\r
+ thePrim.LocalID, DeRezDestination.AgentInventoryTake,\r
+ Client.Inventory.FindFolderForType(AssetType.TrashFolder),\r
+ UUID.Random());\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+using System;\r
+using System.Windows.Forms;\r
+\r
+namespace Radegast\r
+{\r
+ public interface IContextAction : IDisposable\r
+ {\r
+ void IContextAction(RadegastInstance instance);\r
+ ToolStripItem GetToolItem(object target);\r
+ Button GetButton(object target);\r
+ bool IsEnabled(object target);\r
+ string LabelFor(object target);\r
+ bool TypeContributes(Type o);\r
+ bool Contributes(Object o);\r
+ void OnInvoke(object sender, EventArgs e, object target);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+using System;\r
+using OpenMetaverse;\r
+\r
+namespace Radegast\r
+{\r
+ public class RezInventoryObjectAction : ContextAction\r
+ {\r
+ public RezInventoryObjectAction(RadegastInstance inst)\r
+ : base(inst)\r
+ {\r
+ Label = "Rez..";\r
+ ContextType = typeof(InventoryObject);\r
+ }\r
+ public override void OnInvoke(object sender, EventArgs e, object target)\r
+ {\r
+ Client.Inventory.RequestRezFromInventory(\r
+ Client.Network.CurrentSim,\r
+ Client.Self.SimRotation, Client.Self.SimPosition,\r
+ (InventoryItem) (target ?? sender));\r
+ }\r
+ }\r
+}
\ No newline at end of file
/// </summary>\r
public CommandsManager CommandsManager { get { return commandsManager; } }\r
\r
+ /// <summary>\r
+ /// Radegast ContextAction manager for context sensitive actions\r
+ /// </summary>\r
+ public ContextActionsManager ContextActionManager { get; private set; }\r
+\r
private SleekMovement movement;\r
/// <summary>\r
/// Allows key emulation for moving avatar around\r
state = new StateManager(this);\r
mediaManager = new MediaManager(this);\r
commandsManager = new CommandsManager(this);\r
+ ContextActionManager = new ContextActionsManager(this);\r
movement = new SleekMovement(client);\r
\r
InitializeLoggingAndConfig();\r
movement = null;\r
commandsManager.Dispose();\r
commandsManager = null;\r
+ ContextActionManager.Dispose();\r
+ ContextActionManager = null;\r
mediaManager.Dispose();\r
mediaManager = null;\r
state.Dispose();\r
try\r
{\r
commandsManager.LoadType(type);\r
+ ContextActionManager.LoadType(type);\r
}\r
catch (Exception ex)\r
{\r
tab = null;\r
}\r
\r
+\r
+ public void AddContextMenu(Type libomvType, String label, EventHandler handler)\r
+ {\r
+ instance.ContextActionManager.AddContextMenu(libomvType, label, handler);\r
+ }\r
+ public void AddContextMenu(ContextAction handler)\r
+ {\r
+ instance.ContextActionManager.AddContextMenu(handler);\r
+ }\r
+\r
public void AddTab(SleekTab tab)\r
{\r
ToolStripButton button = (ToolStripButton)tstTabs.Items.Add(tab.Label);\r