OSDN Git Service

RAD-448: Copy & Paste into objects inventory, when LlAllowInventoryDrop is TRUE
authorole1986 <ole.k@web.de>
Wed, 15 Jan 2014 13:03:23 +0000 (14:03 +0100)
committerole1986 <ole.k@web.de>
Wed, 15 Jan 2014 13:03:23 +0000 (14:03 +0100)
Radegast/GUI/Consoles/ObjectsConsole.cs

index 37e2db1..764fa56 100644 (file)
-// 
-// Radegast Metaverse Client
-// Copyright (c) 2009-2013, Radegast Development Team
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 
-//     * Redistributions of source code must retain the above copyright notice,
-//       this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in the
-//       documentation and/or other materials provided with the distribution.
-//     * Neither the name of the application "Radegast", nor the names of its
-//       contributors may be used to endorse or promote products derived from
-//       this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// $Id$
-//
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text;
-using System.Timers;
-using System.Windows.Forms;
-#if (COGBOT_LIBOMV || USE_STHREADS)
-using ThreadPoolUtil;
-using Thread = ThreadPoolUtil.Thread;
-using ThreadPool = ThreadPoolUtil.ThreadPool;
-using Monitor = ThreadPoolUtil.Monitor;
-#endif
-using System.Threading;
-using System.Drawing;
-using OpenMetaverse;
-using OpenMetaverse.Assets;
-
-namespace Radegast
-{
-    public partial class ObjectsConsole : UserControl, IContextMenuProvider
-    {
-        public List<Primitive> Prims = new List<Primitive>();
-
-        private RadegastInstance instance;
-        private GridClient client { get { return instance.Client; } }
-        private Primitive currentPrim = new Primitive();
-        private float searchRadius = 40.0f;
-        //public List<InventoryBase> subitems;
-        PropertiesQueue propRequester;
-        private Thread ContentsThread;
-        private ObjectConsoleFilter filter;
-        private ObjectSorter PrimSorter;
-
-        public Primitive CurrentPrim { get { return currentPrim; } }
-
-        public ObjectsConsole(RadegastInstance instance)
-        {
-            InitializeComponent();
-            Disposed += new EventHandler(frmObjects_Disposed);
-
-            this.instance = instance;
-
-            propRequester = new PropertiesQueue(instance);
-            propRequester.OnTick += new PropertiesQueue.TickCallback(propRequester_OnTick);
-
-            btnPointAt.Text = (this.instance.State.IsPointing ? "Unpoint" : "Point At");
-            State_SitStateChanged(this, new SitEventArgs(instance.State.IsSitting));
-
-            nudRadius.Value = (decimal)searchRadius;
-            nudRadius.ValueChanged += nudRadius_ValueChanged;
-
-            PrimSorter = new ObjectSorter(client.Self);
-
-            lstContents.LargeImageList = frmMain.ResourceImages;
-            lstContents.SmallImageList = frmMain.ResourceImages;
-
-            filter = (ObjectConsoleFilter)instance.GlobalSettings["object_console_filter"].AsInteger();
-            comboFilter.SelectedIndex = 0;
-            try
-            {
-                comboFilter.SelectedIndex = (int)filter;
-            }
-            catch { }
-            comboFilter.SelectedIndexChanged += (ssender, se) =>
-            {
-                instance.GlobalSettings["object_console_filter"] = comboFilter.SelectedIndex;
-                filter = (ObjectConsoleFilter)comboFilter.SelectedIndex;
-                btnRefresh_Click(null, null);
-            };
-
-            //if (instance.MonoRuntime)
-            //{
-            //    btnView.Visible = false;
-            //}
-
-            // Callbacks
-            instance.Netcom.ClientDisconnected += new EventHandler<DisconnectedEventArgs>(Netcom_ClientDisconnected);
-            instance.State.SitStateChanged += new EventHandler<SitEventArgs>(State_SitStateChanged);
-            client.Objects.ObjectUpdate += new EventHandler<PrimEventArgs>(Objects_ObjectUpdate);
-            client.Objects.KillObjects += new EventHandler<KillObjectsEventArgs>(Objects_KillObjects);
-            client.Objects.ObjectProperties += new EventHandler<ObjectPropertiesEventArgs>(Objects_ObjectProperties);
-            client.Objects.ObjectPropertiesFamily += new EventHandler<ObjectPropertiesFamilyEventArgs>(Objects_ObjectPropertiesFamily);
-            client.Network.SimChanged += new EventHandler<SimChangedEventArgs>(Network_SimChanged);
-            client.Self.MuteListUpdated += new EventHandler<EventArgs>(Self_MuteListUpdated);
-            instance.Names.NameUpdated += new EventHandler<UUIDNameReplyEventArgs>(Avatars_UUIDNameReply);
-            instance.State.OnWalkStateCanged += new StateManager.WalkStateCanged(State_OnWalkStateCanged);
-        }
-
-        void frmObjects_Disposed(object sender, EventArgs e)
-        {
-            if (ContentsThread != null)
-            {
-                if (ContentsThread.IsAlive) ContentsThread.Abort();
-                ContentsThread = null;
-            }
-
-            propRequester.Dispose();
-            instance.Netcom.ClientDisconnected -= new EventHandler<DisconnectedEventArgs>(Netcom_ClientDisconnected);
-            instance.State.SitStateChanged -= new EventHandler<SitEventArgs>(State_SitStateChanged);
-            client.Objects.ObjectUpdate -= new EventHandler<PrimEventArgs>(Objects_ObjectUpdate);
-            client.Objects.KillObjects -= new EventHandler<KillObjectsEventArgs>(Objects_KillObjects);
-            client.Objects.ObjectProperties -= new EventHandler<ObjectPropertiesEventArgs>(Objects_ObjectProperties);
-            client.Objects.ObjectPropertiesFamily -= new EventHandler<ObjectPropertiesFamilyEventArgs>(Objects_ObjectPropertiesFamily);
-            client.Network.SimChanged -= new EventHandler<SimChangedEventArgs>(Network_SimChanged);
-            client.Self.MuteListUpdated -= new EventHandler<EventArgs>(Self_MuteListUpdated);
-            instance.Names.NameUpdated -= new EventHandler<UUIDNameReplyEventArgs>(Avatars_UUIDNameReply);
-            instance.State.OnWalkStateCanged -= new StateManager.WalkStateCanged(State_OnWalkStateCanged);
-        }
-
-        void State_SitStateChanged(object sender, SitEventArgs e)
-        {
-            if (InvokeRequired)
-            {
-                if (!instance.MonoRuntime || IsHandleCreated)
-                {
-                    BeginInvoke(new MethodInvoker(() => State_SitStateChanged(sender, e)));
-                }
-                return;
-            }
-
-            btnSitOn.Text = (this.instance.State.IsSitting ? "Stand Up" : "Sit On");
-        }
-
-        public void RefreshObjectList()
-        {
-            btnRefresh_Click(this, EventArgs.Empty);
-        }
-
-        public List<Primitive> GetObjectList()
-        {
-            return new List<Primitive>(Prims);
-        }
-
-        void propRequester_OnTick(int remaining)
-        {
-            if (InvokeRequired)
-            {
-                BeginInvoke(new MethodInvoker(delegate()
-                    {
-                        propRequester_OnTick(remaining);
-                    }
-                ));
-                return;
-            }
-
-            StringBuilder sb = new StringBuilder();
-            sb.AppendFormat("Tracking {0} objects", Prims.Count);
-
-            if (remaining > 10)
-            {
-                sb.AppendFormat(", fetching {0} object names.", remaining);
-            }
-            else
-            {
-                sb.Append(".");
-            }
-
-            lock (Prims)
-            {
-                Prims.Sort(PrimSorter);
-                lstPrims.VirtualListSize = Prims.Count;
-            }
-            lstPrims.Invalidate();
-            lblStatus.Text = sb.ToString();
-        }
-
-        void Network_SimChanged(object sender, SimChangedEventArgs e)
-        {
-            if (InvokeRequired)
-            {
-                BeginInvoke(new MethodInvoker(() => Network_SimChanged(sender, e)));
-                return;
-            }
-
-            btnRefresh_Click(null, null);
-        }
-
-        void Avatars_UUIDNameReply(object sender, UUIDNameReplyEventArgs e)
-        {
-            int minIndex = -1;
-            int maxIndex = -1;
-            bool updated = false;
-
-            lock (Prims)
-            {
-                for (int i = 0; i < Prims.Count; i++)
-                {
-                    Primitive prim = Prims[i];
-                    if (prim.Properties != null && e.Names.ContainsKey(prim.Properties.OwnerID))
-                    {
-                        if (minIndex == -1 || i < minIndex) minIndex = i;
-                        if (i > maxIndex) maxIndex = i;
-                        updated = true;
-                    }
-                }
-            }
-
-            if (updated)
-            {
-                if (InvokeRequired)
-                {
-                    BeginInvoke(new MethodInvoker(() =>
-                    {
-                        try
-                        {
-                            lstPrims.RedrawItems(minIndex, maxIndex, true);
-                        }
-                        catch { }
-                    }));
-                }
-                else
-                {
-                    lstPrims.RedrawItems(minIndex, maxIndex, true);
-                }
-            }
-        }
-
-        void UpdateProperties(Primitive.ObjectProperties props)
-        {
-            lock (Prims)
-            {
-                for (int i = 0; i < Prims.Count; i++)
-                {
-                    if (Prims[i].ID == props.ObjectID)
-                    {
-                        Prims[i].Properties = props;
-                        try
-                        {
-                            lstPrims.RedrawItems(i, i, true);
-                        }
-                        catch { }
-                        break;
-                    }
-                }
-            }
-
-            lock (lstChildren.Items)
-            {
-                if (lstChildren.Items.ContainsKey(props.ObjectID.ToString()))
-                {
-                    Primitive prim = lstChildren.Items[props.ObjectID.ToString()].Tag as Primitive;
-                    prim.Properties = props;
-                    lstChildren.Items[props.ObjectID.ToString()].Text = prim.Properties.Name;
-                }
-            }
-
-            if (props.ObjectID == currentPrim.ID)
-            {
-                UpdateCurrentObject(false);
-            }
-        }
-
-        void Objects_ObjectProperties(object sender, ObjectPropertiesEventArgs e)
-        {
-            if (e.Simulator.Handle != client.Network.CurrentSim.Handle)
-            {
-                return;
-            }
-
-            if (InvokeRequired)
-            {
-                BeginInvoke(new MethodInvoker(delegate() { Objects_ObjectProperties(sender, e); }));
-                return;
-            }
-
-            UpdateProperties(e.Properties);
-        }
-
-        void Objects_ObjectPropertiesFamily(object sender, ObjectPropertiesFamilyEventArgs e)
-        {
-            if (e.Simulator.Handle != client.Network.CurrentSim.Handle)
-            {
-                return;
-            }
-
-            if (InvokeRequired)
-            {
-                BeginInvoke(new MethodInvoker(delegate() { Objects_ObjectPropertiesFamily(sender, e); }));
-                return;
-            }
-
-            UpdateProperties(e.Properties);
-        }
-
-
-        void UpdateObjectContents()
-        {
-            if (ContentsThread != null)
-            {
-                if (ContentsThread.IsAlive) ContentsThread.Abort();
-                ContentsThread = null;
-            }
-
-            lstContents.Items.Clear();
-            ListViewItem entry = new ListViewItem();
-            entry.SubItems.Add("Loading...");
-            lstContents.Items.Add(entry);
-
-            ContentsThread = new Thread(new ThreadStart(() =>
-                {
-                    lstContents.Tag = currentPrim;
-                    List<InventoryBase> items = client.Inventory.GetTaskInventory(currentPrim.ID, currentPrim.LocalID, 1000 * 30);
-                    lstContents.Invoke(new MethodInvoker(() => UpdateContentsList(items)));
-                }));
-
-            ContentsThread.IsBackground = true;
-            ContentsThread.Start();
-
-        }
-
-        void UpdateContentsList(List<InventoryBase> items)
-        {
-            //object inventory in liste reinlesen
-            lstContents.Items.Clear();
-            btnOpen.Enabled = false;
-            Primitive prim = (Primitive)lstContents.Tag;
-
-            //subitems = items;
-            if (items == null)
-            {
-                ListViewItem entry = new ListViewItem();
-                entry.SubItems.Add("(failied to fetch contents)");
-                entry.SubItems[0].Font = new System.Drawing.Font(entry.SubItems[0].Font, System.Drawing.FontStyle.Italic);
-                lstContents.Items.Add(entry);
-            }
-            else
-            {
-                if (items.Count == 0)
-                {
-                    ListViewItem entry = new ListViewItem();
-                    entry.SubItems.Add("(empty object)");
-                    entry.SubItems[0].Font = new System.Drawing.Font(entry.SubItems[0].Font, System.Drawing.FontStyle.Italic);
-                    lstContents.Items.Add(entry);
-                }
-                else
-                {
-                    btnOpen.Enabled = prim.Properties != null && prim.Properties.OwnerID == client.Self.AgentID;
-
-                    for (int i = 0; i < items.Count; i++)
-                    {
-                        if (items[i] is InventoryItem)
-                        {
-                            InventoryItem item = (InventoryItem)items[i];
-                            ListViewItem entry = new ListViewItem();
-
-                            entry.ImageIndex = InventoryConsole.GetItemImageIndex(item.AssetType.ToString().ToLower());
-                            entry.Tag = item;
-
-                            ListViewItem.ListViewSubItem sub;
-
-                            entry.SubItems.Add(sub = new ListViewItem.ListViewSubItem()
-                            {
-                                Name = item.UUID.ToString(),
-                                Text = item.Name
-                            });
-
-                            if ((item.Permissions.OwnerMask & PermissionMask.Modify) == 0)
-                                sub.Text += " (no modify)";
-
-                            if ((item.Permissions.OwnerMask & PermissionMask.Copy) == 0)
-                                sub.Text += " (no copy)";
-
-                            if ((item.Permissions.OwnerMask & PermissionMask.Transfer) == 0)
-                                sub.Text += " (no transfer)";
-
-                            sub.Text += " (" + item.InventoryType.ToString() + ")";
-                            entry.ToolTipText = sub.Text;
-
-                            lstContents.Items.Add(entry);
-                        }
-                    }
-                }
-            }
-        }
-
-        private void ctxContents_Opening(object sender, System.ComponentModel.CancelEventArgs e)
-        {
-            e.Cancel = false;
-
-            if (!(lstContents.Tag is Primitive))
-            {
-                e.Cancel = true;
-                return;
-            }
-
-            ctxContents.Items.Clear();
-            Primitive prim = (Primitive)lstContents.Tag;
-            bool canModify = (prim.Flags & PrimFlags.ObjectModify) == PrimFlags.ObjectModify;
-
-            if (lstContents.SelectedItems.Count == 1)
-            {
-                ListViewItem entry = lstContents.SelectedItems[0];
-
-                if (entry.Tag is InventoryItem)
-                {
-                    InventoryItem item = (InventoryItem)entry.Tag;
-
-                    if (canModify)
-                    {
-                        switch (item.InventoryType)
-                        {
-                            case InventoryType.Notecard:
-                                ctxContents.Items.Add("Edit Notecard", null, (object sd, EventArgs ev) =>
-                                    {
-                                        InventoryNotecard inv = (InventoryNotecard)entry.Tag;
-                                        new Notecard(instance, inv, prim) { Detached = true };
-                                    }
-                                );
-                                break;
-
-                            case InventoryType.LSL:
-                                ctxContents.Items.Add("Edit Script", null, (object sd, EventArgs ev) =>
-                                    {
-                                        InventoryLSL inv = (InventoryLSL)entry.Tag;
-                                        new ScriptEditor(instance, inv, prim) { Detached = true };
-                                    }
-                                );
-                                break;
-                        }
-
-                    }
-                }
-            }
-
-            if (lstContents.SelectedItems.Count > 0)
-            {
-                ctxContents.Items.Add("Delete", null, (object sd, EventArgs ev) =>
-                {
-                    foreach (ListViewItem i in lstContents.SelectedItems)
-                        if (i.Tag is InventoryItem)
-                            client.Inventory.RemoveTaskInventory(prim.LocalID, ((InventoryItem)i.Tag).UUID, client.Network.CurrentSim);
-                });
-            }
-
-            if (ctxContents.Items.Count != 0)
-            {
-                ctxContents.Items.Add(new ToolStripSeparator());
-            }
-
-            if (canModify && instance.InventoryClipboard != null)
-            {
-                if (instance.InventoryClipboard.Item is InventoryItem)
-                {
-                    ctxContents.Items.Add("Paste from Inventory", null, (object sd, EventArgs ev) =>
-                    {
-                        if (instance.InventoryClipboard.Item is InventoryLSL)
-                        {
-                            client.Inventory.CopyScriptToTask(prim.LocalID, (InventoryItem)instance.InventoryClipboard.Item, true);
-                        }
-                        else
-                        {
-                            client.Inventory.UpdateTaskInventory(prim.LocalID, (InventoryItem)instance.InventoryClipboard.Item);
-                        }
-                    });
-                }
-                else if (instance.InventoryClipboard.Item is InventoryFolder)
-                {
-                    ctxContents.Items.Add("Paste Folder Contents", null, (object sd, EventArgs ev) =>
-                    {
-                        foreach (InventoryBase oldItem in client.Inventory.Store.GetContents((InventoryFolder)instance.InventoryClipboard.Item))
-                        {
-                            if (oldItem is InventoryItem)
-                            {
-                                if (oldItem is InventoryLSL)
-                                {
-                                    client.Inventory.CopyScriptToTask(prim.LocalID, (InventoryItem)oldItem, true);
-                                }
-                                else
-                                {
-                                    client.Inventory.UpdateTaskInventory(prim.LocalID, (InventoryItem)oldItem);
-                                }
-                            }
-                        }
-                    });
-                }
-            }
-
-            if (canModify)
-            {
-                ctxContents.Items.Add("Open (copy all to inventory)", null, OpenObject);
-            }
-
-            ctxContents.Items.Add("Close", null, btnCloseContents_Click);
-        }
-
-        void OpenObject(object sender, EventArgs e)
-        {
-            if (!(lstContents.Tag is Primitive)) return;
-
-            Primitive prim = (Primitive)lstContents.Tag;
-            if (prim.Properties == null) return;
-
-            List<InventoryItem> items = new List<InventoryItem>();
-
-            foreach (ListViewItem item in lstContents.Items)
-            {
-                if (item.Tag is InventoryItem)
-                    items.Add(item.Tag as InventoryItem);
-            }
-
-            if (items.Count == 0) return;
-
-            UUID folderID = client.Inventory.CreateFolder(client.Inventory.Store.RootFolder.UUID, prim.Properties.Name);
-
-            for (int i = 0; i < items.Count; i++)
-            {
-                client.Inventory.MoveTaskInventory(prim.LocalID, items[i].UUID, folderID, client.Network.CurrentSim);
-            }
-
-            instance.TabConsole.DisplayNotificationInChat("Items from object contents copied to new inventory folder " + prim.Properties.Name);
-
-        }
-
-        void UpdateCurrentObject()
-        {
-            UpdateCurrentObject(true);
-        }
-
-        void UpdateCurrentObject(bool updateContents)
-        {
-            if (currentPrim.Properties == null) return;
-
-            if (InvokeRequired)
-            {
-                BeginInvoke(new MethodInvoker(delegate() { UpdateCurrentObject(updateContents); }));
-                return;
-            }
-
-            // currentItem.Text = GetObjectName(currentPrim);
-
-            txtObjectName.Text = currentPrim.Properties.Name;
-            txtDescription.Text = currentPrim.Properties.Description;
-            if ((currentPrim.Flags & PrimFlags.ObjectModify) == PrimFlags.ObjectModify)
-            {
-                txtObjectName.ReadOnly = txtDescription.ReadOnly = false;
-                gbxObjectDetails.Text = "Object details (you can modify)";
-            }
-            else
-            {
-                txtObjectName.ReadOnly = txtDescription.ReadOnly = true;
-                gbxObjectDetails.Text = "Object details";
-            }
-
-            txtHover.Text = currentPrim.Text;
-            txtOwner.AgentID = currentPrim.Properties.OwnerID;
-            txtCreator.AgentID = currentPrim.Properties.CreatorID;
-
-            Permissions p = currentPrim.Properties.Permissions;
-            cbOwnerModify.Checked = (p.OwnerMask & PermissionMask.Modify) != 0;
-            cbOwnerCopy.Checked = (p.OwnerMask & PermissionMask.Copy) != 0;
-            cbOwnerTransfer.Checked = (p.OwnerMask & PermissionMask.Transfer) != 0;
-
-            cbNextOwnModify.CheckedChanged -= cbNextOwnerUpdate_CheckedChanged;
-            cbNextOwnCopy.CheckedChanged -= cbNextOwnerUpdate_CheckedChanged;
-            cbNextOwnTransfer.CheckedChanged -= cbNextOwnerUpdate_CheckedChanged;
-
-            cbNextOwnModify.Checked = (p.NextOwnerMask & PermissionMask.Modify) != 0;
-            cbNextOwnCopy.Checked = (p.NextOwnerMask & PermissionMask.Copy) != 0;
-            cbNextOwnTransfer.Checked = (p.NextOwnerMask & PermissionMask.Transfer) != 0;
-
-            cbNextOwnModify.CheckedChanged += cbNextOwnerUpdate_CheckedChanged;
-            cbNextOwnCopy.CheckedChanged += cbNextOwnerUpdate_CheckedChanged;
-            cbNextOwnTransfer.CheckedChanged += cbNextOwnerUpdate_CheckedChanged;
-
-            if (currentPrim.Properties.OwnerID == client.Self.AgentID)
-            {
-                cbNextOwnModify.Enabled = cbNextOwnCopy.Enabled = cbNextOwnTransfer.Enabled = true;
-            }
-            else
-            {
-                cbNextOwnModify.Enabled = cbNextOwnCopy.Enabled = cbNextOwnTransfer.Enabled = false;
-            }
-
-            txtPrims.Text = (client.Network.CurrentSim.ObjectsPrimitives.FindAll(
-                delegate(Primitive prim)
-                {
-                    return prim.ParentID == currentPrim.LocalID || prim.LocalID == currentPrim.LocalID;
-                })).Count.ToString();
-
-            if ((currentPrim.Flags & PrimFlags.Money) != 0)
-            {
-                btnPay.Enabled = true;
-            }
-            else
-            {
-                btnPay.Enabled = false;
-            }
-
-            if (currentPrim.Properties.SaleType != SaleType.Not)
-            {
-                btnBuy.Text = string.Format("Buy $L{0}", currentPrim.Properties.SalePrice);
-                btnBuy.Enabled = true;
-            }
-            else
-            {
-                btnBuy.Text = "Buy";
-                btnBuy.Enabled = false;
-            }
-
-            if (gbxContents.Visible /*&& updateContents*/)
-            {
-                UpdateObjectContents();
-            }
-
-            UpdateMuteButton();
-        }
-
-        void Netcom_ClientDisconnected(object sender, DisconnectedEventArgs e)
-        {
-            if (InvokeRequired)
-            {
-                if (!instance.MonoRuntime || IsHandleCreated)
-                {
-                    BeginInvoke(new MethodInvoker(() => Netcom_ClientDisconnected(sender, e)));
-                }
-                return;
-            }
-
-            if (instance.TabConsole.TabExists("objects"))
-            {
-                instance.TabConsole.Tabs["objects"].Close();
-            }
-        }
-
-        private string GetObjectName(Primitive prim, int distance)
-        {
-            string name = "Loading...";
-            string ownerName = "Loading...";
-
-            if (prim.Properties != null)
-            {
-                name = prim.Properties.Name;
-                // prim.Properties.GroupID is the actual group when group owned, not prim.GroupID
-                if (UUID.Zero == prim.Properties.OwnerID &&
-                    PrimFlags.ObjectGroupOwned == (prim.Flags & PrimFlags.ObjectGroupOwned) &&
-                    UUID.Zero != prim.Properties.GroupID)
-                {
-                    System.Threading.AutoResetEvent nameReceivedSignal = new System.Threading.AutoResetEvent(false);
-                    EventHandler<GroupNamesEventArgs> cbGroupName = new EventHandler<GroupNamesEventArgs>(
-                        delegate(object sender, GroupNamesEventArgs e)
-                        {
-                            if (e.GroupNames.ContainsKey(prim.Properties.GroupID))
-                            {
-                                e.GroupNames.TryGetValue(prim.Properties.GroupID, out ownerName);
-                                if (string.IsNullOrEmpty(ownerName))
-                                    ownerName = "Loading...";
-                                if (null != nameReceivedSignal)
-                                    nameReceivedSignal.Set();
-                            }
-                        });
-                    client.Groups.GroupNamesReply += cbGroupName;
-                    client.Groups.RequestGroupName(prim.Properties.GroupID);
-                    nameReceivedSignal.WaitOne(5000, false);
-                    nameReceivedSignal.Close();
-                    client.Groups.GroupNamesReply -= cbGroupName;
-                }
-                else
-                    ownerName = instance.Names.Get(prim.Properties.OwnerID);
-            }
-
-            if (prim.ParentID == client.Self.LocalID)
-            {
-                return string.Format("{0} attached to {1}", name, prim.PrimData.AttachmentPoint.ToString());
-            }
-            else if (ownerName != "Loading...")
-            {
-                return String.Format("{0} ({1}m) owned by {2}", name, distance, ownerName);
-            }
-            else
-            {
-                return String.Format("{0} ({1}m)", name, distance);
-            }
-
-        }
-
-        private string GetObjectName(Primitive prim)
-        {
-            int distance = (int)Vector3.Distance(client.Self.SimPosition, prim.Position);
-            if (prim.ParentID == client.Self.LocalID) distance = 0;
-            return GetObjectName(prim, distance);
-        }
-
-        private void AddPrim(Primitive prim)
-        {
-            lock (Prims)
-            {
-                string name = GetObjectName(prim);
-                if (!Prims.Contains(prim) && (txtSearch.Text.Length == 0 || name.ToLower().Contains(txtSearch.Text.ToLower())))
-                {
-                    Prims.Add(prim);
-                    if (prim.Properties == null)
-                    {
-                        propRequester.RequestProps(prim);
-                    }
-                }
-            }
-        }
-
-        void Objects_ObjectUpdate(object sender, PrimEventArgs e)
-        {
-            if (e.Simulator.Handle != client.Network.CurrentSim.Handle || e.Prim.Position == Vector3.Zero || e.Prim is Avatar) return;
-
-            if (IncludePrim(e.Prim))
-            {
-                if (e.Prim.ParentID == 0)
-                {
-                    int distance = (int)Vector3.Distance(client.Self.SimPosition, e.Prim.Position);
-                    if (distance < searchRadius)
-                    {
-                        AddPrim(e.Prim);
-                    }
-                }
-                else if (e.Prim.ParentID == client.Self.LocalID)
-                {
-                    AddPrim(e.Prim);
-                }
-            }
-
-            if (e.Prim.ID == currentPrim.ID)
-            {
-                if (currentPrim.Properties != null)
-                {
-                    UpdateCurrentObject(false);
-                }
-            }
-        }
-
-        void Objects_KillObjects(object sender, KillObjectsEventArgs e)
-        {
-            if (e.Simulator.Handle != client.Network.CurrentSim.Handle) return;
-
-            lock (Prims)
-            {
-                List<Primitive> killed = Prims.FindAll((p) =>
-                {
-                    for (int i = 0; i < e.ObjectLocalIDs.Length; i++)
-                    {
-                        if (p.LocalID == e.ObjectLocalIDs[i])
-                        {
-                            return true;
-                        }
-                    }
-                    return false;
-                });
-
-                foreach (Primitive prim in killed)
-                {
-                    Prims.Remove(prim);
-                }
-            }
-
-            if (InvokeRequired)
-            {
-                BeginInvoke(new MethodInvoker(() =>
-                {
-                    lstPrims.VirtualListSize = Prims.Count;
-                    lstPrims.Invalidate();
-                }));
-            }
-            else
-            {
-                lstPrims.VirtualListSize = Prims.Count;
-                lstPrims.Invalidate();
-            }
-
-        }
-
-        private bool IncludePrim(Primitive prim)
-        {
-            if ((prim.ParentID == client.Self.LocalID) && (filter == ObjectConsoleFilter.Attached || filter == ObjectConsoleFilter.Both))
-            {
-                return true;
-            }
-            else if ((prim.ParentID == 0) && (filter == ObjectConsoleFilter.Rezzed || filter == ObjectConsoleFilter.Both))
-            {
-                return true;
-            }
-            else
-            {
-                return false;
-            }
-        }
-
-        private void AddAllObjects()
-        {
-            Vector3 location = client.Self.SimPosition;
-
-            lock (Prims)
-            {
-                /*
-                var prims = client.Network.CurrentSim.ObjectsPrimitives.FindAll(prim =>
-                {
-                    return ((prim.ParentID == client.Self.LocalID) && (filter == ObjectConsoleFilter.Attached || filter == ObjectConsoleFilter.Both)) ||
-                        ((prim.ParentID == 0) && (filter == ObjectConsoleFilter.Rezzed || filter == ObjectConsoleFilter.Both));
-                });
-                */
-                client.Network.CurrentSim.ObjectsPrimitives.ForEach(prim =>
-                {
-                    int distance = (int)Vector3.Distance(prim.Position, location);
-                    if (prim.ParentID == client.Self.LocalID)
-                    {
-                        distance = 0;
-                    }
-                    if (IncludePrim(prim) &&
-                        (prim.Position != Vector3.Zero) &&
-                        (distance < searchRadius) &&
-                        (txtSearch.Text.Length == 0 || (prim.Properties != null && prim.Properties.Name.ToLower().Contains(txtSearch.Text.ToLower()))) && //root prims and attachments only
-                        !Prims.Contains(prim))
-                    {
-                        Prims.Add(prim);
-                        if (prim.Properties == null)
-                        {
-                            propRequester.RequestProps(prim);
-                        }
-                    }
-                });
-                Prims.Sort(PrimSorter);
-                lstPrims.VirtualListSize = Prims.Count;
-                lstPrims.Invalidate();
-            }
-        }
-
-        private void btnPointAt_Click(object sender, EventArgs e)
-        {
-            if (btnPointAt.Text == "Point At")
-            {
-                instance.State.SetPointing(currentPrim, 3);
-                btnPointAt.Text = "Unpoint";
-            }
-            else if (btnPointAt.Text == "Unpoint")
-            {
-                instance.State.UnSetPointing();
-                btnPointAt.Text = "Point At";
-            }
-        }
-
-        private void btnSitOn_Click(object sender, EventArgs e)
-        {
-            if (!instance.State.IsSitting)
-            {
-                instance.State.SetSitting(true, currentPrim.ID);
-            }
-            else
-            {
-                instance.State.SetSitting(false, currentPrim.ID);
-            }
-        }
-
-        private void btnTouch_Click(object sender, EventArgs e)
-        {
-            client.Self.Touch(currentPrim.LocalID);
-        }
-
-        private void txtSearch_TextChanged(object sender, EventArgs e)
-        {
-            btnRefresh_Click(null, null);
-        }
-
-        private void btnClear_Click(object sender, EventArgs e)
-        {
-            txtSearch.Clear();
-            txtSearch.Select();
-            btnRefresh_Click(null, null);
-        }
-
-        private void btnRefresh_Click(object sender, EventArgs e)
-        {
-            instance.State.SetDefaultCamera();
-            Cursor.Current = Cursors.WaitCursor;
-            Prims.Clear();
-            AddAllObjects();
-
-            Cursor.Current = Cursors.Default;
-        }
-
-        private void lstPrims_SelectedIndexChanged(object sender, EventArgs e)
-        {
-            if (lstPrims.SelectedIndices.Count == 1)
-            {
-                lock (Prims)
-                {
-                    try
-                    {
-                        currentPrim = Prims[lstPrims.SelectedIndices[0]];
-                    }
-                    catch
-                    {
-                        gbxInworld.Enabled = false;
-                        return;
-                    }
-                }
-
-                gbxInworld.Enabled = true;
-                btnBuy.Tag = currentPrim;
-
-                if (currentPrim.Properties == null || currentPrim.OwnerID == UUID.Zero || (currentPrim.Properties != null && currentPrim.Properties.CreatorID == UUID.Zero))
-                {
-                    client.Objects.SelectObject(client.Network.CurrentSim, currentPrim.LocalID);
-                }
-
-                UpdateCurrentObject();
-                UpdateChildren();
-            }
-            else
-            {
-                lstChildren.Visible = false;
-                gbxInworld.Enabled = false;
-            }
-        }
-
-        private void lstChildren_SelectedIndexChanged(object sender, EventArgs e)
-        {
-            if (lstChildren.SelectedItems.Count == 1)
-            {
-                gbxInworld.Enabled = true;
-                currentPrim = lstChildren.SelectedItems[0].Tag as Primitive;
-                btnBuy.Tag = currentPrim;
-
-                if (currentPrim.Properties == null || (currentPrim.Properties != null && currentPrim.Properties.CreatorID == UUID.Zero))
-                {
-                    client.Objects.SelectObject(client.Network.CurrentSim, currentPrim.LocalID);
-                }
-
-                UpdateCurrentObject();
-            }
-            else
-            {
-                gbxInworld.Enabled = false;
-            }
-        }
-
-        void UpdateChildren()
-        {
-            if (currentPrim == null) return;
-            var prims = client.Network.CurrentSim.ObjectsPrimitives.FindAll((Primitive p) => p.ParentID == currentPrim.LocalID);
-            if (prims == null || prims.Count == 0) return;
-            List<uint> toGetNames = new List<uint>();
-
-            lstChildren.BeginUpdate();
-            lock (lstChildren.Items)
-            {
-                lstChildren.Items.Clear();
-                foreach (var prim in prims)
-                {
-                    var item = new ListViewItem();
-
-                    if (prim.Properties != null)
-                    {
-                        item.Text = prim.Properties.Name;
-                    }
-                    else
-                    {
-                        item.Text = "Loading...";
-                        toGetNames.Add(prim.LocalID);
-                    }
-
-                    item.Tag = prim;
-                    item.Name = prim.ID.ToString();
-                    lstChildren.Items.Add(item);
-                }
-            }
-            lstChildren.EndUpdate();
-            lstChildren.Visible = true;
-            if (toGetNames.Count > 0)
-            {
-                client.Objects.SelectObjects(client.Network.CurrentSim, toGetNames.ToArray(), true);
-            }
-        }
-
-        private void btnPay_Click(object sender, EventArgs e)
-        {
-            (new frmPay(instance, currentPrim.ID, currentPrim.Properties.Name, true)).ShowDialog();
-        }
-
-        private void btnDetach_Click(object sender, EventArgs e)
-        {
-            var toDetach = CurrentOutfitFolder.GetAttachmentItem(currentPrim);
-            if (toDetach != UUID.Zero)
-            {
-                if (client.Inventory.Store.Contains(toDetach))
-                {
-                    instance.COF.Detach(client.Inventory.Store[toDetach] as InventoryItem);
-                }
-            }
-        }
-
-        private void btnView_Click(object sender, EventArgs e)
-        {
-            if (currentPrim.PrimData.PCode != PCode.Prim)
-            {
-                instance.TabConsole.DisplayNotificationInChat("Cannot display objects of that type", ChatBufferTextStyle.Error);
-                return;
-            }
-
-            Rendering.frmPrimWorkshop pw = new Rendering.frmPrimWorkshop(instance, currentPrim.LocalID);
-            pw.Show();
-        }
-
-        private void nudRadius_ValueChanged(object sender, EventArgs e)
-        {
-            searchRadius = (float)nudRadius.Value;
-            btnRefresh_Click(null, null);
-        }
-
-        private void btnBuy_Click(object sender, EventArgs e)
-        {
-            if (lstPrims.SelectedIndices.Count != 1) return;
-            btnBuy.Enabled = false;
-            client.Objects.BuyObject(client.Network.CurrentSim, currentPrim.LocalID, currentPrim.Properties.SaleType, currentPrim.Properties.SalePrice, client.Self.ActiveGroup, client.Inventory.FindFolderForType(AssetType.Object));
-        }
-
-        private void rbDistance_CheckedChanged(object sender, EventArgs e)
-        {
-            if (rbDistance.Checked)
-            {
-                PrimSorter.SortByName = false;
-                lock (Prims) Prims.Sort(PrimSorter);
-                lstPrims.Invalidate();
-            }
-        }
-
-        private void rbName_CheckedChanged(object sender, EventArgs e)
-        {
-            if (rbName.Checked)
-            {
-                PrimSorter.SortByName = true;
-                lock (Prims) Prims.Sort(PrimSorter);
-                lstPrims.Invalidate();
-            }
-        }
-
-        private void btnTurnTo_Click(object sender, EventArgs e)
-        {
-            if (lstPrims.SelectedIndices.Count != 1) return;
-            client.Self.Movement.TurnToward(currentPrim.Position);
-        }
-
-        private void btnWalkTo_Click(object sender, EventArgs e)
-        {
-            if (lstPrims.SelectedIndices.Count != 1) return;
-
-            if (instance.State.IsWalking)
-            {
-                instance.State.EndWalking();
-            }
-            else
-            {
-                instance.State.WalkTo(currentPrim);
-            }
-        }
-
-        void State_OnWalkStateCanged(bool walking)
-        {
-            if (InvokeRequired)
-            {
-                BeginInvoke(new MethodInvoker(delegate() { State_OnWalkStateCanged(walking); }));
-                return;
-            }
-
-            if (walking)
-            {
-                btnWalkTo.Text = "Stop";
-            }
-            else
-            {
-                btnWalkTo.Text = "Walk to";
-                btnRefresh_Click(null, null);
-            }
-        }
-
-        private void nudRadius_KeyUp(object sender, KeyEventArgs e)
-        {
-            if (e.KeyCode == Keys.Enter)
-            {
-                e.SuppressKeyPress = true;
-            }
-        }
-
-        private void nudRadius_KeyDown(object sender, KeyEventArgs e)
-        {
-            if (e.KeyCode == Keys.Enter)
-            {
-                e.SuppressKeyPress = true;
-            }
-        }
-
-        private void ctxMenuObjects_Opening(object sender, System.ComponentModel.CancelEventArgs e)
-        {
-            e.Cancel = false;
-
-            if (lstPrims.SelectedIndices.Count != 1)
-            {
-                e.Cancel = true;
-                return;
-            }
-
-            ctxMenuObjects.Items.Clear();
-            ctxMenuObjects.Items.Add("Click/Touch", null, btnTouch_Click);
-
-            if (currentPrim.ParentID == client.Self.LocalID)
-                ctxMenuObjects.Items.Add("Detach", null, btnDetach_Click);
-
-            if ((currentPrim.Flags & PrimFlags.Money) != 0)
-                ctxMenuObjects.Items.Add("Pay", null, btnPay_Click);
-
-            if (currentPrim.Properties != null && currentPrim.Properties.SaleType != SaleType.Not)
-                ctxMenuObjects.Items.Add(string.Format("Buy for ${0}", currentPrim.Properties.SalePrice), null, btnBuy_Click);
-
-            if (gbxInworld.Visible)
-                ctxMenuObjects.Items.Add("Show Contents", null, btnContents_Click);
-            else
-                ctxMenuObjects.Items.Add("Hide Contents", null, btnCloseContents_Click);
-
-            ctxMenuObjects.Items.Add(this.instance.State.IsSitting ? "Stand Up" : "Sit On", null, btnSitOn_Click);
-            ctxMenuObjects.Items.Add("Turn To", null, btnTurnTo_Click);
-            ctxMenuObjects.Items.Add("Walk To", null, btnWalkTo_Click);
-            ctxMenuObjects.Items.Add(this.instance.State.IsPointing ? "Unpoint" : "Point At", null, btnPointAt_Click);
-            ctxMenuObjects.Items.Add("3D View", null, btnView_Click);
-            ctxMenuObjects.Items.Add("Take", null, btnTake_Click);
-            ctxMenuObjects.Items.Add("Delete", null, btnDelete_Click);
-            ctxMenuObjects.Items.Add("Return", null, btnReturn_Click);
-
-            if (currentPrim.Properties != null)
-            {
-                if (currentPrim.Properties.CreatorID == client.Self.AgentID &&
-                    currentPrim.Properties.OwnerID == client.Self.AgentID)
-                {
-                    ctxMenuObjects.Items.Add("Export", null, btnExport_Click);
-                }
-            }
-
-            if (currentPrim.Properties != null)
-            {
-                bool isMuted = null != client.Self.MuteList.Find(me => me.Type == MuteType.Object && me.ID == currentPrim.ID);
-
-                if (isMuted)
-                {
-                    ctxMenuObjects.Items.Add("Unmute", null, (a, b) =>
-                        {
-                            client.Self.RemoveMuteListEntry(currentPrim.ID, currentPrim.Properties.Name);
-                        });
-                }
-                else
-                {
-                    ctxMenuObjects.Items.Add("Mute", null, (a, b) =>
-                    {
-                        client.Self.UpdateMuteListEntry(MuteType.Object, currentPrim.ID, currentPrim.Properties.Name);
-                    });
-                }
-            }
-
-            //if (currentPrim.MediaURL != null && currentPrim.MediaURL.StartsWith("x-mv:"))
-            //{
-            //    ctxMenuObjects.Items.Add("Test", null, (object menuSender, EventArgs menuE) =>
-            //        {
-            //            client.Objects.RequestObjectMedia(currentPrim.ID, client.Network.CurrentSim, (bool success, string version, MediaEntry[] faceMedia) =>
-            //                {
-            //                    int foo = 1;
-            //                }
-            //            );
-            //        }
-            //    );
-            //}
-
-            instance.ContextActionManager.AddContributions(ctxMenuObjects, currentPrim);
-        }
-
-        public RadegastContextMenuStrip GetContextMenu()
-        {
-            return ctxMenuObjects;
-        }
-
-        private void btnTake_Click(object sender, EventArgs e)
-        {
-            instance.MediaManager.PlayUISound(UISounds.ObjectDelete);
-            client.Inventory.RequestDeRezToInventory(currentPrim.LocalID);
-        }
-
-        private void btnDelete_Click(object sender, EventArgs e)
-        {
-            if (currentPrim.Properties != null && currentPrim.Properties.OwnerID != client.Self.AgentID)
-                btnReturn_Click(sender, e);
-            else
-            {
-                instance.MediaManager.PlayUISound(UISounds.ObjectDelete);
-                client.Inventory.RequestDeRezToInventory(currentPrim.LocalID, DeRezDestination.AgentInventoryTake, client.Inventory.FindFolderForType(AssetType.TrashFolder), UUID.Random());
-            }
-        }
-
-        private void btnReturn_Click(object sender, EventArgs e)
-        {
-            instance.MediaManager.PlayUISound(UISounds.ObjectDelete);
-            client.Inventory.RequestDeRezToInventory(currentPrim.LocalID, DeRezDestination.ReturnToOwner, UUID.Zero, UUID.Random());
-        }
-
-        private void btnCloseContents_Click(object sender, EventArgs e)
-        {
-            gbxContents.Hide();
-            gbxInworld.Show();
-            lstPrims.Focus();
-        }
-
-        private void btnContents_Click(object sender, EventArgs e)
-        {
-            gbxInworld.Hide();
-            gbxContents.Show();
-            UpdateObjectContents();
-            lstContents.Focus();
-        }
-
-        private void btnExport_Click(object sender, EventArgs e)
-        {
-            instance.MainForm.DisplayExportConsole(currentPrim.LocalID);
-        }
-
-        private void lstContents_MouseDoubleClick(object sender, MouseEventArgs e)
-        {
-            if (lstContents.SelectedItems.Count != 1) return;
-
-            ListViewItem contentItem = lstContents.SelectedItems[0];
-
-            if (contentItem.Tag is InventoryLSL)
-            {
-                InventoryLSL inv = (InventoryLSL)contentItem.Tag;
-                Primitive prim = (Primitive)lstContents.Tag;
-                new ScriptEditor(instance, inv, prim) { Detached = true };
-            }
-            else if (contentItem.Tag is InventoryNotecard)
-            {
-                InventoryNotecard inv = (InventoryNotecard)contentItem.Tag;
-                Primitive prim = (Primitive)lstContents.Tag;
-                new Notecard(instance, inv, prim) { Detached = true };
-            }
-
-        }
-
-        private void lstContents_KeyDown(object sender, KeyEventArgs e)
-        {
-            if (e.KeyCode == Keys.Enter)
-            {
-                lstContents_MouseDoubleClick(null, null);
-
-                e.SuppressKeyPress = e.Handled = true;
-                return;
-            }
-            //else if (e.KeyCode == Keys.Apps)
-            //{
-            //    Point pos = new Point(50, 30);
-
-            //    if (lstContents.SelectedItems.Count > 0)
-            //    {
-            //        pos = lstContents.SelectedItems[0].Position;
-            //        pos.Y += 10;
-            //        pos.X += 120;
-            //    }
-
-            //    ctxContents.Show(lstContents, pos);
-
-            //    e.SuppressKeyPress = e.Handled = true;
-            //    return;
-            //}
-        }
-
-        void Self_MuteListUpdated(object sender, EventArgs e)
-        {
-            if (InvokeRequired)
-            {
-                if (!instance.MonoRuntime || IsHandleCreated)
-                {
-                    BeginInvoke(new MethodInvoker(() => Self_MuteListUpdated(sender, e)));
-                }
-                return;
-            }
-
-            if (lstPrims.SelectedIndices.Count != 1) return;
-
-            UpdateMuteButton();
-        }
-
-        void UpdateMuteButton()
-        {
-            bool isMuted = null != client.Self.MuteList.Find(me => me.Type == MuteType.Object && me.ID == currentPrim.ID);
-
-            if (isMuted)
-            {
-                btnMute.Text = "Unmute";
-            }
-            else
-            {
-                btnMute.Text = "Mute";
-            }
-        }
-
-        private void btnMute_Click(object sender, EventArgs e)
-        {
-            if (lstPrims.SelectedIndices.Count != 1) return;
-
-            if (currentPrim.Properties == null) return;
-
-            if (btnMute.Text == "Mute")
-            {
-                client.Self.UpdateMuteListEntry(MuteType.Object, currentPrim.ID, currentPrim.Properties.Name);
-            }
-            else
-            {
-                client.Self.RemoveMuteListEntry(currentPrim.ID, currentPrim.Properties.Name);
-            }
-        }
-
-        private void txtObjectName_Leave(object sender, EventArgs e)
-        {
-            if (currentPrim == null) return;
-            if (currentPrim.Properties == null || (currentPrim.Properties != null && currentPrim.Properties.Name != txtObjectName.Text))
-            {
-                client.Objects.SetName(client.Network.CurrentSim, currentPrim.LocalID, txtObjectName.Text);
-            }
-        }
-
-        private void txtDescription_Leave(object sender, EventArgs e)
-        {
-            if (currentPrim == null) return;
-            if (currentPrim.Properties == null || (currentPrim.Properties != null && currentPrim.Properties.Description != txtDescription.Text))
-            {
-                client.Objects.SetDescription(client.Network.CurrentSim, currentPrim.LocalID, txtDescription.Text);
-            }
-        }
-
-        private void cbNextOwnerUpdate_CheckedChanged(object sender, EventArgs e)
-        {
-            CheckBox cb = (CheckBox)sender;
-            PermissionMask pm = PermissionMask.None;
-
-            if (cb == cbNextOwnCopy) pm = PermissionMask.Copy;
-            if (cb == cbNextOwnModify) pm = PermissionMask.Modify;
-            if (cb == cbNextOwnTransfer) pm = PermissionMask.Transfer;
-
-            if (pm == PermissionMask.None) return;
-
-            client.Objects.SetPermissions(client.Network.CurrentSim, new List<uint>() { currentPrim.LocalID }, PermissionWho.NextOwner, pm, cb.Checked);
-        }
-
-        private void lstPrims_Enter(object sender, EventArgs e)
-        {
-            lstPrims_SelectedIndexChanged(sender, EventArgs.Empty);
-        }
-
-        private void lstChildren_Enter(object sender, EventArgs e)
-        {
-            lstChildren_SelectedIndexChanged(sender, EventArgs.Empty);
-        }
-
-        private void lstPrims_DoubleClick(object sender, EventArgs e)
-        {
-            btnView.PerformClick();
-        }
-
-        private void lstPrims_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
-        {
-            Primitive prim = null;
-            try
-            {
-                lock (Prims)
-                {
-                    prim = Prims[e.ItemIndex];
-                }
-            }
-            catch
-            {
-                e.Item = new ListViewItem();
-                return;
-            }
-
-            string name = GetObjectName(prim);
-            var item = new ListViewItem(name);
-            item.Tag = prim;
-            item.Name = prim.ID.ToString();
-            e.Item = item;
-        }
-
-    }
-
-    public enum ObjectConsoleFilter : int
-    {
-        Rezzed = 0,
-        Attached = 1,
-        Both = 2
-    }
-
-    public class ObjectSorter : IComparer<Primitive>
-    {
-        private AgentManager me;
-        private bool sortByName = false;
-
-        public bool SortByName { get { return sortByName; } set { sortByName = value; } }
-
-        public ObjectSorter(AgentManager me)
-        {
-            this.me = me;
-        }
-
-        private int NameCompare(Primitive prim1, Primitive prim2)
-        {
-            if (prim1.Properties == null && prim2.Properties == null)
-            {
-                return 0;
-            }
-            else if (prim1.Properties != null && prim2.Properties == null)
-            {
-                return -1;
-            }
-            else if (prim1.Properties == null && prim2.Properties != null)
-            {
-                return 1;
-            }
-
-            return string.Compare(prim1.Properties.Name, prim2.Properties.Name);
-        }
-        //this routine should return -1 if xy and 0 if x==y.
-        // for our sample we'll just use string comparison
-        public int Compare(Primitive prim1, Primitive prim2)
-        {
-            if (sortByName)
-            {
-                return NameCompare(prim1, prim2);
-            }
-
-            float dist1 = prim1.ParentID == me.LocalID ? 0 : Vector3.Distance(me.SimPosition, prim1.Position);
-            float dist2 = prim2.ParentID == me.LocalID ? 0 : Vector3.Distance(me.SimPosition, prim2.Position);
-
-            if (dist1 == dist2)
-            {
-                return NameCompare(prim1, prim2);
-            }
-            else
-            {
-                if (dist1 < dist2)
-                {
-                    return -1;
-                }
-                return 1;
-            }
-        }
-    }
-
-    public class PropertiesQueue : IDisposable
-    {
-        Object sync = new Object();
-        RadegastInstance instance;
-        System.Timers.Timer qTimer;
-        Queue<Primitive> props = new Queue<Primitive>();
-
-        public delegate void TickCallback(int remaining);
-        public event TickCallback OnTick;
-
-        public PropertiesQueue(RadegastInstance instance)
-        {
-            this.instance = instance;
-            qTimer = new System.Timers.Timer(2500);
-            qTimer.Enabled = true;
-            qTimer.Elapsed += new ElapsedEventHandler(qTimer_Elapsed);
-        }
-
-        public void RequestProps(Primitive prim)
-        {
-            lock (sync)
-            {
-                if (!props.Contains(prim))
-                {
-                    props.Enqueue(prim);
-                }
-            }
-        }
-
-        void qTimer_Elapsed(object sender, ElapsedEventArgs e)
-        {
-            lock (sync)
-            {
-                for (int i = 0; i < 25 && props.Count > 0; i++)
-                {
-                    Primitive prim = props.Dequeue();
-                    if (prim.ParentID == 0)
-                    {
-                        instance.Client.Objects.RequestObjectPropertiesFamily(
-                            instance.Client.Network.CurrentSim, prim.ID, true);
-                    }
-                    else
-                    {
-                        instance.Client.Objects.SelectObject(instance.Client.Network.CurrentSim,
-                            prim.LocalID, true);
-                    }
-                }
-
-                if (OnTick != null)
-                {
-                    OnTick(props.Count);
-                }
-            }
-        }
-
-        public void Dispose()
-        {
-            if (qTimer != null)
-            {
-                qTimer.Elapsed -= new ElapsedEventHandler(qTimer_Elapsed);
-                qTimer.Enabled = false;
-                qTimer = null;
-            }
-            props = null;
-            instance = null;
-        }
-    }
-
+// \r
+// Radegast Metaverse Client\r
+// Copyright (c) 2009-2013, Radegast Development Team\r
+// All rights reserved.\r
+// \r
+// Redistribution and use in source and binary forms, with or without\r
+// modification, are permitted provided that the following conditions are met:\r
+// \r
+//     * Redistributions of source code must retain the above copyright notice,\r
+//       this list of conditions and the following disclaimer.\r
+//     * Redistributions in binary form must reproduce the above copyright\r
+//       notice, this list of conditions and the following disclaimer in the\r
+//       documentation and/or other materials provided with the distribution.\r
+//     * Neither the name of the application "Radegast", nor the names of its\r
+//       contributors may be used to endorse or promote products derived from\r
+//       this software without specific prior written permission.\r
+// \r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+//\r
+// $Id$\r
+//\r
+using System;\r
+using System.Collections;\r
+using System.Collections.Generic;\r
+using System.Text;\r
+using System.Timers;\r
+using System.Windows.Forms;\r
+#if (COGBOT_LIBOMV || USE_STHREADS)\r
+using ThreadPoolUtil;\r
+using Thread = ThreadPoolUtil.Thread;\r
+using ThreadPool = ThreadPoolUtil.ThreadPool;\r
+using Monitor = ThreadPoolUtil.Monitor;\r
+#endif\r
+using System.Threading;\r
+using System.Drawing;\r
+using OpenMetaverse;\r
+using OpenMetaverse.Assets;\r
+\r
+namespace Radegast\r
+{\r
+    public partial class ObjectsConsole : UserControl, IContextMenuProvider\r
+    {\r
+        public List<Primitive> Prims = new List<Primitive>();\r
+\r
+        private RadegastInstance instance;\r
+        private GridClient client { get { return instance.Client; } }\r
+        private Primitive currentPrim = new Primitive();\r
+        private float searchRadius = 40.0f;\r
+        //public List<InventoryBase> subitems;\r
+        PropertiesQueue propRequester;\r
+        private Thread ContentsThread;\r
+        private ObjectConsoleFilter filter;\r
+        private ObjectSorter PrimSorter;\r
+\r
+        public Primitive CurrentPrim { get { return currentPrim; } }\r
+\r
+        public ObjectsConsole(RadegastInstance instance)\r
+        {\r
+            InitializeComponent();\r
+            Disposed += new EventHandler(frmObjects_Disposed);\r
+\r
+            this.instance = instance;\r
+\r
+            propRequester = new PropertiesQueue(instance);\r
+            propRequester.OnTick += new PropertiesQueue.TickCallback(propRequester_OnTick);\r
+\r
+            btnPointAt.Text = (this.instance.State.IsPointing ? "Unpoint" : "Point At");\r
+            State_SitStateChanged(this, new SitEventArgs(instance.State.IsSitting));\r
+\r
+            nudRadius.Value = (decimal)searchRadius;\r
+            nudRadius.ValueChanged += nudRadius_ValueChanged;\r
+\r
+            PrimSorter = new ObjectSorter(client.Self);\r
+\r
+            lstContents.LargeImageList = frmMain.ResourceImages;\r
+            lstContents.SmallImageList = frmMain.ResourceImages;\r
+\r
+            filter = (ObjectConsoleFilter)instance.GlobalSettings["object_console_filter"].AsInteger();\r
+            comboFilter.SelectedIndex = 0;\r
+            try\r
+            {\r
+                comboFilter.SelectedIndex = (int)filter;\r
+            }\r
+            catch { }\r
+            comboFilter.SelectedIndexChanged += (ssender, se) =>\r
+            {\r
+                instance.GlobalSettings["object_console_filter"] = comboFilter.SelectedIndex;\r
+                filter = (ObjectConsoleFilter)comboFilter.SelectedIndex;\r
+                btnRefresh_Click(null, null);\r
+            };\r
+\r
+            //if (instance.MonoRuntime)\r
+            //{\r
+            //    btnView.Visible = false;\r
+            //}\r
+\r
+            // Callbacks\r
+            instance.Netcom.ClientDisconnected += new EventHandler<DisconnectedEventArgs>(Netcom_ClientDisconnected);\r
+            instance.State.SitStateChanged += new EventHandler<SitEventArgs>(State_SitStateChanged);\r
+            client.Objects.ObjectUpdate += new EventHandler<PrimEventArgs>(Objects_ObjectUpdate);\r
+            client.Objects.KillObjects += new EventHandler<KillObjectsEventArgs>(Objects_KillObjects);\r
+            client.Objects.ObjectProperties += new EventHandler<ObjectPropertiesEventArgs>(Objects_ObjectProperties);\r
+            client.Objects.ObjectPropertiesFamily += new EventHandler<ObjectPropertiesFamilyEventArgs>(Objects_ObjectPropertiesFamily);\r
+            client.Network.SimChanged += new EventHandler<SimChangedEventArgs>(Network_SimChanged);\r
+            client.Self.MuteListUpdated += new EventHandler<EventArgs>(Self_MuteListUpdated);\r
+            instance.Names.NameUpdated += new EventHandler<UUIDNameReplyEventArgs>(Avatars_UUIDNameReply);\r
+            instance.State.OnWalkStateCanged += new StateManager.WalkStateCanged(State_OnWalkStateCanged);\r
+        }\r
+\r
+        void frmObjects_Disposed(object sender, EventArgs e)\r
+        {\r
+            if (ContentsThread != null)\r
+            {\r
+                if (ContentsThread.IsAlive) ContentsThread.Abort();\r
+                ContentsThread = null;\r
+            }\r
+\r
+            propRequester.Dispose();\r
+            instance.Netcom.ClientDisconnected -= new EventHandler<DisconnectedEventArgs>(Netcom_ClientDisconnected);\r
+            instance.State.SitStateChanged -= new EventHandler<SitEventArgs>(State_SitStateChanged);\r
+            client.Objects.ObjectUpdate -= new EventHandler<PrimEventArgs>(Objects_ObjectUpdate);\r
+            client.Objects.KillObjects -= new EventHandler<KillObjectsEventArgs>(Objects_KillObjects);\r
+            client.Objects.ObjectProperties -= new EventHandler<ObjectPropertiesEventArgs>(Objects_ObjectProperties);\r
+            client.Objects.ObjectPropertiesFamily -= new EventHandler<ObjectPropertiesFamilyEventArgs>(Objects_ObjectPropertiesFamily);\r
+            client.Network.SimChanged -= new EventHandler<SimChangedEventArgs>(Network_SimChanged);\r
+            client.Self.MuteListUpdated -= new EventHandler<EventArgs>(Self_MuteListUpdated);\r
+            instance.Names.NameUpdated -= new EventHandler<UUIDNameReplyEventArgs>(Avatars_UUIDNameReply);\r
+            instance.State.OnWalkStateCanged -= new StateManager.WalkStateCanged(State_OnWalkStateCanged);\r
+        }\r
+\r
+        void State_SitStateChanged(object sender, SitEventArgs e)\r
+        {\r
+            if (InvokeRequired)\r
+            {\r
+                if (!instance.MonoRuntime || IsHandleCreated)\r
+                {\r
+                    BeginInvoke(new MethodInvoker(() => State_SitStateChanged(sender, e)));\r
+                }\r
+                return;\r
+            }\r
+\r
+            btnSitOn.Text = (this.instance.State.IsSitting ? "Stand Up" : "Sit On");\r
+        }\r
+\r
+        public void RefreshObjectList()\r
+        {\r
+            btnRefresh_Click(this, EventArgs.Empty);\r
+        }\r
+\r
+        public List<Primitive> GetObjectList()\r
+        {\r
+            return new List<Primitive>(Prims);\r
+        }\r
+\r
+        void propRequester_OnTick(int remaining)\r
+        {\r
+            if (InvokeRequired)\r
+            {\r
+                BeginInvoke(new MethodInvoker(delegate()\r
+                    {\r
+                        propRequester_OnTick(remaining);\r
+                    }\r
+                ));\r
+                return;\r
+            }\r
+\r
+            StringBuilder sb = new StringBuilder();\r
+            sb.AppendFormat("Tracking {0} objects", Prims.Count);\r
+\r
+            if (remaining > 10)\r
+            {\r
+                sb.AppendFormat(", fetching {0} object names.", remaining);\r
+            }\r
+            else\r
+            {\r
+                sb.Append(".");\r
+            }\r
+\r
+            lock (Prims)\r
+            {\r
+                Prims.Sort(PrimSorter);\r
+                lstPrims.VirtualListSize = Prims.Count;\r
+            }\r
+            lstPrims.Invalidate();\r
+            lblStatus.Text = sb.ToString();\r
+        }\r
+\r
+        void Network_SimChanged(object sender, SimChangedEventArgs e)\r
+        {\r
+            if (InvokeRequired)\r
+            {\r
+                BeginInvoke(new MethodInvoker(() => Network_SimChanged(sender, e)));\r
+                return;\r
+            }\r
+\r
+            btnRefresh_Click(null, null);\r
+        }\r
+\r
+        void Avatars_UUIDNameReply(object sender, UUIDNameReplyEventArgs e)\r
+        {\r
+            int minIndex = -1;\r
+            int maxIndex = -1;\r
+            bool updated = false;\r
+\r
+            lock (Prims)\r
+            {\r
+                for (int i = 0; i < Prims.Count; i++)\r
+                {\r
+                    Primitive prim = Prims[i];\r
+                    if (prim.Properties != null && e.Names.ContainsKey(prim.Properties.OwnerID))\r
+                    {\r
+                        if (minIndex == -1 || i < minIndex) minIndex = i;\r
+                        if (i > maxIndex) maxIndex = i;\r
+                        updated = true;\r
+                    }\r
+                }\r
+            }\r
+\r
+            if (updated)\r
+            {\r
+                if (InvokeRequired)\r
+                {\r
+                    BeginInvoke(new MethodInvoker(() =>\r
+                    {\r
+                        try\r
+                        {\r
+                            lstPrims.RedrawItems(minIndex, maxIndex, true);\r
+                        }\r
+                        catch { }\r
+                    }));\r
+                }\r
+                else\r
+                {\r
+                    lstPrims.RedrawItems(minIndex, maxIndex, true);\r
+                }\r
+            }\r
+        }\r
+\r
+        void UpdateProperties(Primitive.ObjectProperties props)\r
+        {\r
+            lock (Prims)\r
+            {\r
+                for (int i = 0; i < Prims.Count; i++)\r
+                {\r
+                    if (Prims[i].ID == props.ObjectID)\r
+                    {\r
+                        Prims[i].Properties = props;\r
+                        try\r
+                        {\r
+                            lstPrims.RedrawItems(i, i, true);\r
+                        }\r
+                        catch { }\r
+                        break;\r
+                    }\r
+                }\r
+            }\r
+\r
+            lock (lstChildren.Items)\r
+            {\r
+                if (lstChildren.Items.ContainsKey(props.ObjectID.ToString()))\r
+                {\r
+                    Primitive prim = lstChildren.Items[props.ObjectID.ToString()].Tag as Primitive;\r
+                    prim.Properties = props;\r
+                    lstChildren.Items[props.ObjectID.ToString()].Text = prim.Properties.Name;\r
+                }\r
+            }\r
+\r
+            if (props.ObjectID == currentPrim.ID)\r
+            {\r
+                UpdateCurrentObject(false);\r
+            }\r
+        }\r
+\r
+        void Objects_ObjectProperties(object sender, ObjectPropertiesEventArgs e)\r
+        {\r
+            if (e.Simulator.Handle != client.Network.CurrentSim.Handle)\r
+            {\r
+                return;\r
+            }\r
+\r
+            if (InvokeRequired)\r
+            {\r
+                BeginInvoke(new MethodInvoker(delegate() { Objects_ObjectProperties(sender, e); }));\r
+                return;\r
+            }\r
+\r
+            UpdateProperties(e.Properties);\r
+        }\r
+\r
+        void Objects_ObjectPropertiesFamily(object sender, ObjectPropertiesFamilyEventArgs e)\r
+        {\r
+            if (e.Simulator.Handle != client.Network.CurrentSim.Handle)\r
+            {\r
+                return;\r
+            }\r
+\r
+            if (InvokeRequired)\r
+            {\r
+                BeginInvoke(new MethodInvoker(delegate() { Objects_ObjectPropertiesFamily(sender, e); }));\r
+                return;\r
+            }\r
+\r
+            UpdateProperties(e.Properties);\r
+        }\r
+\r
+\r
+        void UpdateObjectContents()\r
+        {\r
+            if (ContentsThread != null)\r
+            {\r
+                if (ContentsThread.IsAlive) ContentsThread.Abort();\r
+                ContentsThread = null;\r
+            }\r
+\r
+            lstContents.Items.Clear();\r
+            ListViewItem entry = new ListViewItem();\r
+            entry.SubItems.Add("Loading...");\r
+            lstContents.Items.Add(entry);\r
+\r
+            ContentsThread = new Thread(new ThreadStart(() =>\r
+                {\r
+                    lstContents.Tag = currentPrim;\r
+                    List<InventoryBase> items = client.Inventory.GetTaskInventory(currentPrim.ID, currentPrim.LocalID, 1000 * 30);\r
+                    lstContents.Invoke(new MethodInvoker(() => UpdateContentsList(items)));\r
+                }));\r
+\r
+            ContentsThread.IsBackground = true;\r
+            ContentsThread.Start();\r
+\r
+        }\r
+\r
+        void UpdateContentsList(List<InventoryBase> items)\r
+        {\r
+            //object inventory in liste reinlesen\r
+            lstContents.Items.Clear();\r
+            btnOpen.Enabled = false;\r
+            Primitive prim = (Primitive)lstContents.Tag;\r
+\r
+            //subitems = items;\r
+            if (items == null)\r
+            {\r
+                ListViewItem entry = new ListViewItem();\r
+                entry.SubItems.Add("(failied to fetch contents)");\r
+                entry.SubItems[0].Font = new System.Drawing.Font(entry.SubItems[0].Font, System.Drawing.FontStyle.Italic);\r
+                lstContents.Items.Add(entry);\r
+            }\r
+            else\r
+            {\r
+                if (items.Count == 0)\r
+                {\r
+                    ListViewItem entry = new ListViewItem();\r
+                    entry.SubItems.Add("(empty object)");\r
+                    entry.SubItems[0].Font = new System.Drawing.Font(entry.SubItems[0].Font, System.Drawing.FontStyle.Italic);\r
+                    lstContents.Items.Add(entry);\r
+                }\r
+                else\r
+                {\r
+                    btnOpen.Enabled = prim.Properties != null && prim.Properties.OwnerID == client.Self.AgentID;\r
+\r
+                    for (int i = 0; i < items.Count; i++)\r
+                    {\r
+                        if (items[i] is InventoryItem)\r
+                        {\r
+                            InventoryItem item = (InventoryItem)items[i];\r
+                            ListViewItem entry = new ListViewItem();\r
+\r
+                            entry.ImageIndex = InventoryConsole.GetItemImageIndex(item.AssetType.ToString().ToLower());\r
+                            entry.Tag = item;\r
+\r
+                            ListViewItem.ListViewSubItem sub;\r
+\r
+                            entry.SubItems.Add(sub = new ListViewItem.ListViewSubItem()\r
+                            {\r
+                                Name = item.UUID.ToString(),\r
+                                Text = item.Name\r
+                            });\r
+\r
+                            if ((item.Permissions.OwnerMask & PermissionMask.Modify) == 0)\r
+                                sub.Text += " (no modify)";\r
+\r
+                            if ((item.Permissions.OwnerMask & PermissionMask.Copy) == 0)\r
+                                sub.Text += " (no copy)";\r
+\r
+                            if ((item.Permissions.OwnerMask & PermissionMask.Transfer) == 0)\r
+                                sub.Text += " (no transfer)";\r
+\r
+                            sub.Text += " (" + item.InventoryType.ToString() + ")";\r
+                            entry.ToolTipText = sub.Text;\r
+\r
+                            lstContents.Items.Add(entry);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+\r
+        private void ctxContents_Opening(object sender, System.ComponentModel.CancelEventArgs e)\r
+        {\r
+            e.Cancel = false;\r
+\r
+            if (!(lstContents.Tag is Primitive))\r
+            {\r
+                e.Cancel = true;\r
+                return;\r
+            }\r
+\r
+            ctxContents.Items.Clear();\r
+            Primitive prim = (Primitive)lstContents.Tag;\r
+            bool canModify = (prim.Flags & PrimFlags.ObjectModify) == PrimFlags.ObjectModify;\r
+\r
+            if (lstContents.SelectedItems.Count == 1)\r
+            {\r
+                ListViewItem entry = lstContents.SelectedItems[0];\r
+\r
+                if (entry.Tag is InventoryItem)\r
+                {\r
+                    InventoryItem item = (InventoryItem)entry.Tag;\r
+\r
+                    if (canModify)\r
+                    {\r
+                        switch (item.InventoryType)\r
+                        {\r
+                            case InventoryType.Notecard:\r
+                                ctxContents.Items.Add("Edit Notecard", null, (object sd, EventArgs ev) =>\r
+                                    {\r
+                                        InventoryNotecard inv = (InventoryNotecard)entry.Tag;\r
+                                        new Notecard(instance, inv, prim) { Detached = true };\r
+                                    }\r
+                                );\r
+                                break;\r
+\r
+                            case InventoryType.LSL:\r
+                                ctxContents.Items.Add("Edit Script", null, (object sd, EventArgs ev) =>\r
+                                    {\r
+                                        InventoryLSL inv = (InventoryLSL)entry.Tag;\r
+                                        new ScriptEditor(instance, inv, prim) { Detached = true };\r
+                                    }\r
+                                );\r
+                                break;\r
+                        }\r
+\r
+                    }\r
+                }\r
+            }\r
+\r
+            if (lstContents.SelectedItems.Count > 0)\r
+            {\r
+                ctxContents.Items.Add("Delete", null, (object sd, EventArgs ev) =>\r
+                {\r
+                    foreach (ListViewItem i in lstContents.SelectedItems)\r
+                        if (i.Tag is InventoryItem)\r
+                            client.Inventory.RemoveTaskInventory(prim.LocalID, ((InventoryItem)i.Tag).UUID, client.Network.CurrentSim);\r
+                });\r
+            }\r
+\r
+            if (ctxContents.Items.Count != 0)\r
+            {\r
+                ctxContents.Items.Add(new ToolStripSeparator());\r
+            }\r
+\r
+            if ((canModify || (prim.Flags & PrimFlags.AllowInventoryDrop) == PrimFlags.AllowInventoryDrop) && instance.InventoryClipboard != null)\r
+            {\r
+                if (instance.InventoryClipboard.Item is InventoryItem)\r
+                {\r
+                    ctxContents.Items.Add("Paste from Inventory", null, (object sd, EventArgs ev) =>\r
+                    {\r
+                        if (instance.InventoryClipboard.Item is InventoryLSL)\r
+                        {\r
+                            client.Inventory.CopyScriptToTask(prim.LocalID, (InventoryItem)instance.InventoryClipboard.Item, true);\r
+                        }\r
+                        else\r
+                        {\r
+                            client.Inventory.UpdateTaskInventory(prim.LocalID, (InventoryItem)instance.InventoryClipboard.Item);\r
+                        }\r
+                    });\r
+                }\r
+                else if (instance.InventoryClipboard.Item is InventoryFolder)\r
+                {\r
+                    ctxContents.Items.Add("Paste Folder Contents", null, (object sd, EventArgs ev) =>\r
+                    {\r
+                        foreach (InventoryBase oldItem in client.Inventory.Store.GetContents((InventoryFolder)instance.InventoryClipboard.Item))\r
+                        {\r
+                            if (oldItem is InventoryItem)\r
+                            {\r
+                                if (oldItem is InventoryLSL)\r
+                                {\r
+                                    client.Inventory.CopyScriptToTask(prim.LocalID, (InventoryItem)oldItem, true);\r
+                                }\r
+                                else\r
+                                {\r
+                                    client.Inventory.UpdateTaskInventory(prim.LocalID, (InventoryItem)oldItem);\r
+                                }\r
+                            }\r
+                        }\r
+                    });\r
+                }\r
+            }\r
+\r
+            if (canModify)\r
+            {\r
+                ctxContents.Items.Add("Open (copy all to inventory)", null, OpenObject);\r
+            }\r
+\r
+            ctxContents.Items.Add("Close", null, btnCloseContents_Click);\r
+        }\r
+\r
+        void OpenObject(object sender, EventArgs e)\r
+        {\r
+            if (!(lstContents.Tag is Primitive)) return;\r
+\r
+            Primitive prim = (Primitive)lstContents.Tag;\r
+            if (prim.Properties == null) return;\r
+\r
+            List<InventoryItem> items = new List<InventoryItem>();\r
+\r
+            foreach (ListViewItem item in lstContents.Items)\r
+            {\r
+                if (item.Tag is InventoryItem)\r
+                    items.Add(item.Tag as InventoryItem);\r
+            }\r
+\r
+            if (items.Count == 0) return;\r
+\r
+            UUID folderID = client.Inventory.CreateFolder(client.Inventory.Store.RootFolder.UUID, prim.Properties.Name);\r
+\r
+            for (int i = 0; i < items.Count; i++)\r
+            {\r
+                client.Inventory.MoveTaskInventory(prim.LocalID, items[i].UUID, folderID, client.Network.CurrentSim);\r
+            }\r
+\r
+            instance.TabConsole.DisplayNotificationInChat("Items from object contents copied to new inventory folder " + prim.Properties.Name);\r
+\r
+        }\r
+\r
+        void UpdateCurrentObject()\r
+        {\r
+            UpdateCurrentObject(true);\r
+        }\r
+\r
+        void UpdateCurrentObject(bool updateContents)\r
+        {\r
+            if (currentPrim.Properties == null) return;\r
+\r
+            if (InvokeRequired)\r
+            {\r
+                BeginInvoke(new MethodInvoker(delegate() { UpdateCurrentObject(updateContents); }));\r
+                return;\r
+            }\r
+\r
+            // currentItem.Text = GetObjectName(currentPrim);\r
+\r
+            txtObjectName.Text = currentPrim.Properties.Name;\r
+            txtDescription.Text = currentPrim.Properties.Description;\r
+            if ((currentPrim.Flags & PrimFlags.ObjectModify) == PrimFlags.ObjectModify)\r
+            {\r
+                txtObjectName.ReadOnly = txtDescription.ReadOnly = false;\r
+                gbxObjectDetails.Text = "Object details (you can modify)";\r
+            }\r
+            else\r
+            {\r
+                txtObjectName.ReadOnly = txtDescription.ReadOnly = true;\r
+                gbxObjectDetails.Text = "Object details";\r
+            }\r
+\r
+            txtHover.Text = currentPrim.Text;\r
+            txtOwner.AgentID = currentPrim.Properties.OwnerID;\r
+            txtCreator.AgentID = currentPrim.Properties.CreatorID;\r
+\r
+            Permissions p = currentPrim.Properties.Permissions;\r
+            cbOwnerModify.Checked = (p.OwnerMask & PermissionMask.Modify) != 0;\r
+            cbOwnerCopy.Checked = (p.OwnerMask & PermissionMask.Copy) != 0;\r
+            cbOwnerTransfer.Checked = (p.OwnerMask & PermissionMask.Transfer) != 0;\r
+\r
+            cbNextOwnModify.CheckedChanged -= cbNextOwnerUpdate_CheckedChanged;\r
+            cbNextOwnCopy.CheckedChanged -= cbNextOwnerUpdate_CheckedChanged;\r
+            cbNextOwnTransfer.CheckedChanged -= cbNextOwnerUpdate_CheckedChanged;\r
+\r
+            cbNextOwnModify.Checked = (p.NextOwnerMask & PermissionMask.Modify) != 0;\r
+            cbNextOwnCopy.Checked = (p.NextOwnerMask & PermissionMask.Copy) != 0;\r
+            cbNextOwnTransfer.Checked = (p.NextOwnerMask & PermissionMask.Transfer) != 0;\r
+\r
+            cbNextOwnModify.CheckedChanged += cbNextOwnerUpdate_CheckedChanged;\r
+            cbNextOwnCopy.CheckedChanged += cbNextOwnerUpdate_CheckedChanged;\r
+            cbNextOwnTransfer.CheckedChanged += cbNextOwnerUpdate_CheckedChanged;\r
+\r
+            if (currentPrim.Properties.OwnerID == client.Self.AgentID)\r
+            {\r
+                cbNextOwnModify.Enabled = cbNextOwnCopy.Enabled = cbNextOwnTransfer.Enabled = true;\r
+            }\r
+            else\r
+            {\r
+                cbNextOwnModify.Enabled = cbNextOwnCopy.Enabled = cbNextOwnTransfer.Enabled = false;\r
+            }\r
+\r
+            txtPrims.Text = (client.Network.CurrentSim.ObjectsPrimitives.FindAll(\r
+                delegate(Primitive prim)\r
+                {\r
+                    return prim.ParentID == currentPrim.LocalID || prim.LocalID == currentPrim.LocalID;\r
+                })).Count.ToString();\r
+\r
+            if ((currentPrim.Flags & PrimFlags.Money) != 0)\r
+            {\r
+                btnPay.Enabled = true;\r
+            }\r
+            else\r
+            {\r
+                btnPay.Enabled = false;\r
+            }\r
+\r
+            if (currentPrim.Properties.SaleType != SaleType.Not)\r
+            {\r
+                btnBuy.Text = string.Format("Buy $L{0}", currentPrim.Properties.SalePrice);\r
+                btnBuy.Enabled = true;\r
+            }\r
+            else\r
+            {\r
+                btnBuy.Text = "Buy";\r
+                btnBuy.Enabled = false;\r
+            }\r
+\r
+            if (gbxContents.Visible /*&& updateContents*/)\r
+            {\r
+                UpdateObjectContents();\r
+            }\r
+\r
+            UpdateMuteButton();\r
+        }\r
+\r
+        void Netcom_ClientDisconnected(object sender, DisconnectedEventArgs e)\r
+        {\r
+            if (InvokeRequired)\r
+            {\r
+                if (!instance.MonoRuntime || IsHandleCreated)\r
+                {\r
+                    BeginInvoke(new MethodInvoker(() => Netcom_ClientDisconnected(sender, e)));\r
+                }\r
+                return;\r
+            }\r
+\r
+            if (instance.TabConsole.TabExists("objects"))\r
+            {\r
+                instance.TabConsole.Tabs["objects"].Close();\r
+            }\r
+        }\r
+\r
+        private string GetObjectName(Primitive prim, int distance)\r
+        {\r
+            string name = "Loading...";\r
+            string ownerName = "Loading...";\r
+\r
+            if (prim.Properties != null)\r
+            {\r
+                name = prim.Properties.Name;\r
+                // prim.Properties.GroupID is the actual group when group owned, not prim.GroupID\r
+                if (UUID.Zero == prim.Properties.OwnerID &&\r
+                    PrimFlags.ObjectGroupOwned == (prim.Flags & PrimFlags.ObjectGroupOwned) &&\r
+                    UUID.Zero != prim.Properties.GroupID)\r
+                {\r
+                    System.Threading.AutoResetEvent nameReceivedSignal = new System.Threading.AutoResetEvent(false);\r
+                    EventHandler<GroupNamesEventArgs> cbGroupName = new EventHandler<GroupNamesEventArgs>(\r
+                        delegate(object sender, GroupNamesEventArgs e)\r
+                        {\r
+                            if (e.GroupNames.ContainsKey(prim.Properties.GroupID))\r
+                            {\r
+                                e.GroupNames.TryGetValue(prim.Properties.GroupID, out ownerName);\r
+                                if (string.IsNullOrEmpty(ownerName))\r
+                                    ownerName = "Loading...";\r
+                                if (null != nameReceivedSignal)\r
+                                    nameReceivedSignal.Set();\r
+                            }\r
+                        });\r
+                    client.Groups.GroupNamesReply += cbGroupName;\r
+                    client.Groups.RequestGroupName(prim.Properties.GroupID);\r
+                    nameReceivedSignal.WaitOne(5000, false);\r
+                    nameReceivedSignal.Close();\r
+                    client.Groups.GroupNamesReply -= cbGroupName;\r
+                }\r
+                else\r
+                    ownerName = instance.Names.Get(prim.Properties.OwnerID);\r
+            }\r
+\r
+            if (prim.ParentID == client.Self.LocalID)\r
+            {\r
+                return string.Format("{0} attached to {1}", name, prim.PrimData.AttachmentPoint.ToString());\r
+            }\r
+            else if (ownerName != "Loading...")\r
+            {\r
+                return String.Format("{0} ({1}m) owned by {2}", name, distance, ownerName);\r
+            }\r
+            else\r
+            {\r
+                return String.Format("{0} ({1}m)", name, distance);\r
+            }\r
+\r
+        }\r
+\r
+        private string GetObjectName(Primitive prim)\r
+        {\r
+            int distance = (int)Vector3.Distance(client.Self.SimPosition, prim.Position);\r
+            if (prim.ParentID == client.Self.LocalID) distance = 0;\r
+            return GetObjectName(prim, distance);\r
+        }\r
+\r
+        private void AddPrim(Primitive prim)\r
+        {\r
+            lock (Prims)\r
+            {\r
+                string name = GetObjectName(prim);\r
+                if (!Prims.Contains(prim) && (txtSearch.Text.Length == 0 || name.ToLower().Contains(txtSearch.Text.ToLower())))\r
+                {\r
+                    Prims.Add(prim);\r
+                    if (prim.Properties == null)\r
+                    {\r
+                        propRequester.RequestProps(prim);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+\r
+        void Objects_ObjectUpdate(object sender, PrimEventArgs e)\r
+        {\r
+            if (e.Simulator.Handle != client.Network.CurrentSim.Handle || e.Prim.Position == Vector3.Zero || e.Prim is Avatar) return;\r
+\r
+            if (IncludePrim(e.Prim))\r
+            {\r
+                if (e.Prim.ParentID == 0)\r
+                {\r
+                    int distance = (int)Vector3.Distance(client.Self.SimPosition, e.Prim.Position);\r
+                    if (distance < searchRadius)\r
+                    {\r
+                        AddPrim(e.Prim);\r
+                    }\r
+                }\r
+                else if (e.Prim.ParentID == client.Self.LocalID)\r
+                {\r
+                    AddPrim(e.Prim);\r
+                }\r
+            }\r
+\r
+            if (e.Prim.ID == currentPrim.ID)\r
+            {\r
+                if (currentPrim.Properties != null)\r
+                {\r
+                    UpdateCurrentObject(false);\r
+                }\r
+            }\r
+        }\r
+\r
+        void Objects_KillObjects(object sender, KillObjectsEventArgs e)\r
+        {\r
+            if (e.Simulator.Handle != client.Network.CurrentSim.Handle) return;\r
+\r
+            lock (Prims)\r
+            {\r
+                List<Primitive> killed = Prims.FindAll((p) =>\r
+                {\r
+                    for (int i = 0; i < e.ObjectLocalIDs.Length; i++)\r
+                    {\r
+                        if (p.LocalID == e.ObjectLocalIDs[i])\r
+                        {\r
+                            return true;\r
+                        }\r
+                    }\r
+                    return false;\r
+                });\r
+\r
+                foreach (Primitive prim in killed)\r
+                {\r
+                    Prims.Remove(prim);\r
+                }\r
+            }\r
+\r
+            if (InvokeRequired)\r
+            {\r
+                BeginInvoke(new MethodInvoker(() =>\r
+                {\r
+                    lstPrims.VirtualListSize = Prims.Count;\r
+                    lstPrims.Invalidate();\r
+                }));\r
+            }\r
+            else\r
+            {\r
+                lstPrims.VirtualListSize = Prims.Count;\r
+                lstPrims.Invalidate();\r
+            }\r
+\r
+        }\r
+\r
+        private bool IncludePrim(Primitive prim)\r
+        {\r
+            if ((prim.ParentID == client.Self.LocalID) && (filter == ObjectConsoleFilter.Attached || filter == ObjectConsoleFilter.Both))\r
+            {\r
+                return true;\r
+            }\r
+            else if ((prim.ParentID == 0) && (filter == ObjectConsoleFilter.Rezzed || filter == ObjectConsoleFilter.Both))\r
+            {\r
+                return true;\r
+            }\r
+            else\r
+            {\r
+                return false;\r
+            }\r
+        }\r
+\r
+        private void AddAllObjects()\r
+        {\r
+            Vector3 location = client.Self.SimPosition;\r
+\r
+            lock (Prims)\r
+            {\r
+                /*\r
+                var prims = client.Network.CurrentSim.ObjectsPrimitives.FindAll(prim =>\r
+                {\r
+                    return ((prim.ParentID == client.Self.LocalID) && (filter == ObjectConsoleFilter.Attached || filter == ObjectConsoleFilter.Both)) ||\r
+                        ((prim.ParentID == 0) && (filter == ObjectConsoleFilter.Rezzed || filter == ObjectConsoleFilter.Both));\r
+                });\r
+                */\r
+                client.Network.CurrentSim.ObjectsPrimitives.ForEach(prim =>\r
+                {\r
+                    int distance = (int)Vector3.Distance(prim.Position, location);\r
+                    if (prim.ParentID == client.Self.LocalID)\r
+                    {\r
+                        distance = 0;\r
+                    }\r
+                    if (IncludePrim(prim) &&\r
+                        (prim.Position != Vector3.Zero) &&\r
+                        (distance < searchRadius) &&\r
+                        (txtSearch.Text.Length == 0 || (prim.Properties != null && prim.Properties.Name.ToLower().Contains(txtSearch.Text.ToLower()))) && //root prims and attachments only\r
+                        !Prims.Contains(prim))\r
+                    {\r
+                        Prims.Add(prim);\r
+                        if (prim.Properties == null)\r
+                        {\r
+                            propRequester.RequestProps(prim);\r
+                        }\r
+                    }\r
+                });\r
+                Prims.Sort(PrimSorter);\r
+                lstPrims.VirtualListSize = Prims.Count;\r
+                lstPrims.Invalidate();\r
+            }\r
+        }\r
+\r
+        private void btnPointAt_Click(object sender, EventArgs e)\r
+        {\r
+            if (btnPointAt.Text == "Point At")\r
+            {\r
+                instance.State.SetPointing(currentPrim, 3);\r
+                btnPointAt.Text = "Unpoint";\r
+            }\r
+            else if (btnPointAt.Text == "Unpoint")\r
+            {\r
+                instance.State.UnSetPointing();\r
+                btnPointAt.Text = "Point At";\r
+            }\r
+        }\r
+\r
+        private void btnSitOn_Click(object sender, EventArgs e)\r
+        {\r
+            if (!instance.State.IsSitting)\r
+            {\r
+                instance.State.SetSitting(true, currentPrim.ID);\r
+            }\r
+            else\r
+            {\r
+                instance.State.SetSitting(false, currentPrim.ID);\r
+            }\r
+        }\r
+\r
+        private void btnTouch_Click(object sender, EventArgs e)\r
+        {\r
+            client.Self.Touch(currentPrim.LocalID);\r
+        }\r
+\r
+        private void txtSearch_TextChanged(object sender, EventArgs e)\r
+        {\r
+            btnRefresh_Click(null, null);\r
+        }\r
+\r
+        private void btnClear_Click(object sender, EventArgs e)\r
+        {\r
+            txtSearch.Clear();\r
+            txtSearch.Select();\r
+            btnRefresh_Click(null, null);\r
+        }\r
+\r
+        private void btnRefresh_Click(object sender, EventArgs e)\r
+        {\r
+            instance.State.SetDefaultCamera();\r
+            Cursor.Current = Cursors.WaitCursor;\r
+            Prims.Clear();\r
+            AddAllObjects();\r
+\r
+            Cursor.Current = Cursors.Default;\r
+        }\r
+\r
+        private void lstPrims_SelectedIndexChanged(object sender, EventArgs e)\r
+        {\r
+            if (lstPrims.SelectedIndices.Count == 1)\r
+            {\r
+                lock (Prims)\r
+                {\r
+                    try\r
+                    {\r
+                        currentPrim = Prims[lstPrims.SelectedIndices[0]];\r
+                    }\r
+                    catch\r
+                    {\r
+                        gbxInworld.Enabled = false;\r
+                        return;\r
+                    }\r
+                }\r
+\r
+                gbxInworld.Enabled = true;\r
+                btnBuy.Tag = currentPrim;\r
+\r
+                if (currentPrim.Properties == null || currentPrim.OwnerID == UUID.Zero || (currentPrim.Properties != null && currentPrim.Properties.CreatorID == UUID.Zero))\r
+                {\r
+                    client.Objects.SelectObject(client.Network.CurrentSim, currentPrim.LocalID);\r
+                }\r
+\r
+                UpdateCurrentObject();\r
+                UpdateChildren();\r
+            }\r
+            else\r
+            {\r
+                lstChildren.Visible = false;\r
+                gbxInworld.Enabled = false;\r
+            }\r
+        }\r
+\r
+        private void lstChildren_SelectedIndexChanged(object sender, EventArgs e)\r
+        {\r
+            if (lstChildren.SelectedItems.Count == 1)\r
+            {\r
+                gbxInworld.Enabled = true;\r
+                currentPrim = lstChildren.SelectedItems[0].Tag as Primitive;\r
+                btnBuy.Tag = currentPrim;\r
+\r
+                if (currentPrim.Properties == null || (currentPrim.Properties != null && currentPrim.Properties.CreatorID == UUID.Zero))\r
+                {\r
+                    client.Objects.SelectObject(client.Network.CurrentSim, currentPrim.LocalID);\r
+                }\r
+\r
+                UpdateCurrentObject();\r
+            }\r
+            else\r
+            {\r
+                gbxInworld.Enabled = false;\r
+            }\r
+        }\r
+\r
+        void UpdateChildren()\r
+        {\r
+            if (currentPrim == null) return;\r
+            var prims = client.Network.CurrentSim.ObjectsPrimitives.FindAll((Primitive p) => p.ParentID == currentPrim.LocalID);\r
+            if (prims == null || prims.Count == 0) return;\r
+            List<uint> toGetNames = new List<uint>();\r
+\r
+            lstChildren.BeginUpdate();\r
+            lock (lstChildren.Items)\r
+            {\r
+                lstChildren.Items.Clear();\r
+                foreach (var prim in prims)\r
+                {\r
+                    var item = new ListViewItem();\r
+\r
+                    if (prim.Properties != null)\r
+                    {\r
+                        item.Text = prim.Properties.Name;\r
+                    }\r
+                    else\r
+                    {\r
+                        item.Text = "Loading...";\r
+                        toGetNames.Add(prim.LocalID);\r
+                    }\r
+\r
+                    item.Tag = prim;\r
+                    item.Name = prim.ID.ToString();\r
+                    lstChildren.Items.Add(item);\r
+                }\r
+            }\r
+            lstChildren.EndUpdate();\r
+            lstChildren.Visible = true;\r
+            if (toGetNames.Count > 0)\r
+            {\r
+                client.Objects.SelectObjects(client.Network.CurrentSim, toGetNames.ToArray(), true);\r
+            }\r
+        }\r
+\r
+        private void btnPay_Click(object sender, EventArgs e)\r
+        {\r
+            (new frmPay(instance, currentPrim.ID, currentPrim.Properties.Name, true)).ShowDialog();\r
+        }\r
+\r
+        private void btnDetach_Click(object sender, EventArgs e)\r
+        {\r
+            var toDetach = CurrentOutfitFolder.GetAttachmentItem(currentPrim);\r
+            if (toDetach != UUID.Zero)\r
+            {\r
+                if (client.Inventory.Store.Contains(toDetach))\r
+                {\r
+                    instance.COF.Detach(client.Inventory.Store[toDetach] as InventoryItem);\r
+                }\r
+            }\r
+        }\r
+\r
+        private void btnView_Click(object sender, EventArgs e)\r
+        {\r
+            if (currentPrim.PrimData.PCode != PCode.Prim)\r
+            {\r
+                instance.TabConsole.DisplayNotificationInChat("Cannot display objects of that type", ChatBufferTextStyle.Error);\r
+                return;\r
+            }\r
+\r
+            Rendering.frmPrimWorkshop pw = new Rendering.frmPrimWorkshop(instance, currentPrim.LocalID);\r
+            pw.Show();\r
+        }\r
+\r
+        private void nudRadius_ValueChanged(object sender, EventArgs e)\r
+        {\r
+            searchRadius = (float)nudRadius.Value;\r
+            btnRefresh_Click(null, null);\r
+        }\r
+\r
+        private void btnBuy_Click(object sender, EventArgs e)\r
+        {\r
+            if (lstPrims.SelectedIndices.Count != 1) return;\r
+            btnBuy.Enabled = false;\r
+            client.Objects.BuyObject(client.Network.CurrentSim, currentPrim.LocalID, currentPrim.Properties.SaleType, currentPrim.Properties.SalePrice, client.Self.ActiveGroup, client.Inventory.FindFolderForType(AssetType.Object));\r
+        }\r
+\r
+        private void rbDistance_CheckedChanged(object sender, EventArgs e)\r
+        {\r
+            if (rbDistance.Checked)\r
+            {\r
+                PrimSorter.SortByName = false;\r
+                lock (Prims) Prims.Sort(PrimSorter);\r
+                lstPrims.Invalidate();\r
+            }\r
+        }\r
+\r
+        private void rbName_CheckedChanged(object sender, EventArgs e)\r
+        {\r
+            if (rbName.Checked)\r
+            {\r
+                PrimSorter.SortByName = true;\r
+                lock (Prims) Prims.Sort(PrimSorter);\r
+                lstPrims.Invalidate();\r
+            }\r
+        }\r
+\r
+        private void btnTurnTo_Click(object sender, EventArgs e)\r
+        {\r
+            if (lstPrims.SelectedIndices.Count != 1) return;\r
+            client.Self.Movement.TurnToward(currentPrim.Position);\r
+        }\r
+\r
+        private void btnWalkTo_Click(object sender, EventArgs e)\r
+        {\r
+            if (lstPrims.SelectedIndices.Count != 1) return;\r
+\r
+            if (instance.State.IsWalking)\r
+            {\r
+                instance.State.EndWalking();\r
+            }\r
+            else\r
+            {\r
+                instance.State.WalkTo(currentPrim);\r
+            }\r
+        }\r
+\r
+        void State_OnWalkStateCanged(bool walking)\r
+        {\r
+            if (InvokeRequired)\r
+            {\r
+                BeginInvoke(new MethodInvoker(delegate() { State_OnWalkStateCanged(walking); }));\r
+                return;\r
+            }\r
+\r
+            if (walking)\r
+            {\r
+                btnWalkTo.Text = "Stop";\r
+            }\r
+            else\r
+            {\r
+                btnWalkTo.Text = "Walk to";\r
+                btnRefresh_Click(null, null);\r
+            }\r
+        }\r
+\r
+        private void nudRadius_KeyUp(object sender, KeyEventArgs e)\r
+        {\r
+            if (e.KeyCode == Keys.Enter)\r
+            {\r
+                e.SuppressKeyPress = true;\r
+            }\r
+        }\r
+\r
+        private void nudRadius_KeyDown(object sender, KeyEventArgs e)\r
+        {\r
+            if (e.KeyCode == Keys.Enter)\r
+            {\r
+                e.SuppressKeyPress = true;\r
+            }\r
+        }\r
+\r
+        private void ctxMenuObjects_Opening(object sender, System.ComponentModel.CancelEventArgs e)\r
+        {\r
+            e.Cancel = false;\r
+\r
+            if (lstPrims.SelectedIndices.Count != 1)\r
+            {\r
+                e.Cancel = true;\r
+                return;\r
+            }\r
+\r
+            ctxMenuObjects.Items.Clear();\r
+            ctxMenuObjects.Items.Add("Click/Touch", null, btnTouch_Click);\r
+\r
+            if (currentPrim.ParentID == client.Self.LocalID)\r
+                ctxMenuObjects.Items.Add("Detach", null, btnDetach_Click);\r
+\r
+            if ((currentPrim.Flags & PrimFlags.Money) != 0)\r
+                ctxMenuObjects.Items.Add("Pay", null, btnPay_Click);\r
+\r
+            if (currentPrim.Properties != null && currentPrim.Properties.SaleType != SaleType.Not)\r
+                ctxMenuObjects.Items.Add(string.Format("Buy for ${0}", currentPrim.Properties.SalePrice), null, btnBuy_Click);\r
+\r
+            if (gbxInworld.Visible)\r
+                ctxMenuObjects.Items.Add("Show Contents", null, btnContents_Click);\r
+            else\r
+                ctxMenuObjects.Items.Add("Hide Contents", null, btnCloseContents_Click);\r
+\r
+            ctxMenuObjects.Items.Add(this.instance.State.IsSitting ? "Stand Up" : "Sit On", null, btnSitOn_Click);\r
+            ctxMenuObjects.Items.Add("Turn To", null, btnTurnTo_Click);\r
+            ctxMenuObjects.Items.Add("Walk To", null, btnWalkTo_Click);\r
+            ctxMenuObjects.Items.Add(this.instance.State.IsPointing ? "Unpoint" : "Point At", null, btnPointAt_Click);\r
+            ctxMenuObjects.Items.Add("3D View", null, btnView_Click);\r
+            ctxMenuObjects.Items.Add("Take", null, btnTake_Click);\r
+            ctxMenuObjects.Items.Add("Delete", null, btnDelete_Click);\r
+            ctxMenuObjects.Items.Add("Return", null, btnReturn_Click);\r
+\r
+            if (currentPrim.Properties != null)\r
+            {\r
+                if (currentPrim.Properties.CreatorID == client.Self.AgentID &&\r
+                    currentPrim.Properties.OwnerID == client.Self.AgentID)\r
+                {\r
+                    ctxMenuObjects.Items.Add("Export", null, btnExport_Click);\r
+                }\r
+            }\r
+\r
+            if (currentPrim.Properties != null)\r
+            {\r
+                bool isMuted = null != client.Self.MuteList.Find(me => me.Type == MuteType.Object && me.ID == currentPrim.ID);\r
+\r
+                if (isMuted)\r
+                {\r
+                    ctxMenuObjects.Items.Add("Unmute", null, (a, b) =>\r
+                        {\r
+                            client.Self.RemoveMuteListEntry(currentPrim.ID, currentPrim.Properties.Name);\r
+                        });\r
+                }\r
+                else\r
+                {\r
+                    ctxMenuObjects.Items.Add("Mute", null, (a, b) =>\r
+                    {\r
+                        client.Self.UpdateMuteListEntry(MuteType.Object, currentPrim.ID, currentPrim.Properties.Name);\r
+                    });\r
+                }\r
+            }\r
+\r
+            //if (currentPrim.MediaURL != null && currentPrim.MediaURL.StartsWith("x-mv:"))\r
+            //{\r
+            //    ctxMenuObjects.Items.Add("Test", null, (object menuSender, EventArgs menuE) =>\r
+            //        {\r
+            //            client.Objects.RequestObjectMedia(currentPrim.ID, client.Network.CurrentSim, (bool success, string version, MediaEntry[] faceMedia) =>\r
+            //                {\r
+            //                    int foo = 1;\r
+            //                }\r
+            //            );\r
+            //        }\r
+            //    );\r
+            //}\r
+\r
+            instance.ContextActionManager.AddContributions(ctxMenuObjects, currentPrim);\r
+        }\r
+\r
+        public RadegastContextMenuStrip GetContextMenu()\r
+        {\r
+            return ctxMenuObjects;\r
+        }\r
+\r
+        private void btnTake_Click(object sender, EventArgs e)\r
+        {\r
+            instance.MediaManager.PlayUISound(UISounds.ObjectDelete);\r
+            client.Inventory.RequestDeRezToInventory(currentPrim.LocalID);\r
+        }\r
+\r
+        private void btnDelete_Click(object sender, EventArgs e)\r
+        {\r
+            if (currentPrim.Properties != null && currentPrim.Properties.OwnerID != client.Self.AgentID)\r
+                btnReturn_Click(sender, e);\r
+            else\r
+            {\r
+                instance.MediaManager.PlayUISound(UISounds.ObjectDelete);\r
+                client.Inventory.RequestDeRezToInventory(currentPrim.LocalID, DeRezDestination.AgentInventoryTake, client.Inventory.FindFolderForType(AssetType.TrashFolder), UUID.Random());\r
+            }\r
+        }\r
+\r
+        private void btnReturn_Click(object sender, EventArgs e)\r
+        {\r
+            instance.MediaManager.PlayUISound(UISounds.ObjectDelete);\r
+            client.Inventory.RequestDeRezToInventory(currentPrim.LocalID, DeRezDestination.ReturnToOwner, UUID.Zero, UUID.Random());\r
+        }\r
+\r
+        private void btnCloseContents_Click(object sender, EventArgs e)\r
+        {\r
+            gbxContents.Hide();\r
+            gbxInworld.Show();\r
+            lstPrims.Focus();\r
+        }\r
+\r
+        private void btnContents_Click(object sender, EventArgs e)\r
+        {\r
+            gbxInworld.Hide();\r
+            gbxContents.Show();\r
+            UpdateObjectContents();\r
+            lstContents.Focus();\r
+        }\r
+\r
+        private void btnExport_Click(object sender, EventArgs e)\r
+        {\r
+            instance.MainForm.DisplayExportConsole(currentPrim.LocalID);\r
+        }\r
+\r
+        private void lstContents_MouseDoubleClick(object sender, MouseEventArgs e)\r
+        {\r
+            if (lstContents.SelectedItems.Count != 1) return;\r
+\r
+            ListViewItem contentItem = lstContents.SelectedItems[0];\r
+\r
+            if (contentItem.Tag is InventoryLSL)\r
+            {\r
+                InventoryLSL inv = (InventoryLSL)contentItem.Tag;\r
+                Primitive prim = (Primitive)lstContents.Tag;\r
+                new ScriptEditor(instance, inv, prim) { Detached = true };\r
+            }\r
+            else if (contentItem.Tag is InventoryNotecard)\r
+            {\r
+                InventoryNotecard inv = (InventoryNotecard)contentItem.Tag;\r
+                Primitive prim = (Primitive)lstContents.Tag;\r
+                new Notecard(instance, inv, prim) { Detached = true };\r
+            }\r
+\r
+        }\r
+\r
+        private void lstContents_KeyDown(object sender, KeyEventArgs e)\r
+        {\r
+            if (e.KeyCode == Keys.Enter)\r
+            {\r
+                lstContents_MouseDoubleClick(null, null);\r
+\r
+                e.SuppressKeyPress = e.Handled = true;\r
+                return;\r
+            }\r
+            //else if (e.KeyCode == Keys.Apps)\r
+            //{\r
+            //    Point pos = new Point(50, 30);\r
+\r
+            //    if (lstContents.SelectedItems.Count > 0)\r
+            //    {\r
+            //        pos = lstContents.SelectedItems[0].Position;\r
+            //        pos.Y += 10;\r
+            //        pos.X += 120;\r
+            //    }\r
+\r
+            //    ctxContents.Show(lstContents, pos);\r
+\r
+            //    e.SuppressKeyPress = e.Handled = true;\r
+            //    return;\r
+            //}\r
+        }\r
+\r
+        void Self_MuteListUpdated(object sender, EventArgs e)\r
+        {\r
+            if (InvokeRequired)\r
+            {\r
+                if (!instance.MonoRuntime || IsHandleCreated)\r
+                {\r
+                    BeginInvoke(new MethodInvoker(() => Self_MuteListUpdated(sender, e)));\r
+                }\r
+                return;\r
+            }\r
+\r
+            if (lstPrims.SelectedIndices.Count != 1) return;\r
+\r
+            UpdateMuteButton();\r
+        }\r
+\r
+        void UpdateMuteButton()\r
+        {\r
+            bool isMuted = null != client.Self.MuteList.Find(me => me.Type == MuteType.Object && me.ID == currentPrim.ID);\r
+\r
+            if (isMuted)\r
+            {\r
+                btnMute.Text = "Unmute";\r
+            }\r
+            else\r
+            {\r
+                btnMute.Text = "Mute";\r
+            }\r
+        }\r
+\r
+        private void btnMute_Click(object sender, EventArgs e)\r
+        {\r
+            if (lstPrims.SelectedIndices.Count != 1) return;\r
+\r
+            if (currentPrim.Properties == null) return;\r
+\r
+            if (btnMute.Text == "Mute")\r
+            {\r
+                client.Self.UpdateMuteListEntry(MuteType.Object, currentPrim.ID, currentPrim.Properties.Name);\r
+            }\r
+            else\r
+            {\r
+                client.Self.RemoveMuteListEntry(currentPrim.ID, currentPrim.Properties.Name);\r
+            }\r
+        }\r
+\r
+        private void txtObjectName_Leave(object sender, EventArgs e)\r
+        {\r
+            if (currentPrim == null) return;\r
+            if (currentPrim.Properties == null || (currentPrim.Properties != null && currentPrim.Properties.Name != txtObjectName.Text))\r
+            {\r
+                client.Objects.SetName(client.Network.CurrentSim, currentPrim.LocalID, txtObjectName.Text);\r
+            }\r
+        }\r
+\r
+        private void txtDescription_Leave(object sender, EventArgs e)\r
+        {\r
+            if (currentPrim == null) return;\r
+            if (currentPrim.Properties == null || (currentPrim.Properties != null && currentPrim.Properties.Description != txtDescription.Text))\r
+            {\r
+                client.Objects.SetDescription(client.Network.CurrentSim, currentPrim.LocalID, txtDescription.Text);\r
+            }\r
+        }\r
+\r
+        private void cbNextOwnerUpdate_CheckedChanged(object sender, EventArgs e)\r
+        {\r
+            CheckBox cb = (CheckBox)sender;\r
+            PermissionMask pm = PermissionMask.None;\r
+\r
+            if (cb == cbNextOwnCopy) pm = PermissionMask.Copy;\r
+            if (cb == cbNextOwnModify) pm = PermissionMask.Modify;\r
+            if (cb == cbNextOwnTransfer) pm = PermissionMask.Transfer;\r
+\r
+            if (pm == PermissionMask.None) return;\r
+\r
+            client.Objects.SetPermissions(client.Network.CurrentSim, new List<uint>() { currentPrim.LocalID }, PermissionWho.NextOwner, pm, cb.Checked);\r
+        }\r
+\r
+        private void lstPrims_Enter(object sender, EventArgs e)\r
+        {\r
+            lstPrims_SelectedIndexChanged(sender, EventArgs.Empty);\r
+        }\r
+\r
+        private void lstChildren_Enter(object sender, EventArgs e)\r
+        {\r
+            lstChildren_SelectedIndexChanged(sender, EventArgs.Empty);\r
+        }\r
+\r
+        private void lstPrims_DoubleClick(object sender, EventArgs e)\r
+        {\r
+            btnView.PerformClick();\r
+        }\r
+\r
+        private void lstPrims_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)\r
+        {\r
+            Primitive prim = null;\r
+            try\r
+            {\r
+                lock (Prims)\r
+                {\r
+                    prim = Prims[e.ItemIndex];\r
+                }\r
+            }\r
+            catch\r
+            {\r
+                e.Item = new ListViewItem();\r
+                return;\r
+            }\r
+\r
+            string name = GetObjectName(prim);\r
+            var item = new ListViewItem(name);\r
+            item.Tag = prim;\r
+            item.Name = prim.ID.ToString();\r
+            e.Item = item;\r
+        }\r
+\r
+    }\r
+\r
+    public enum ObjectConsoleFilter : int\r
+    {\r
+        Rezzed = 0,\r
+        Attached = 1,\r
+        Both = 2\r
+    }\r
+\r
+    public class ObjectSorter : IComparer<Primitive>\r
+    {\r
+        private AgentManager me;\r
+        private bool sortByName = false;\r
+\r
+        public bool SortByName { get { return sortByName; } set { sortByName = value; } }\r
+\r
+        public ObjectSorter(AgentManager me)\r
+        {\r
+            this.me = me;\r
+        }\r
+\r
+        private int NameCompare(Primitive prim1, Primitive prim2)\r
+        {\r
+            if (prim1.Properties == null && prim2.Properties == null)\r
+            {\r
+                return 0;\r
+            }\r
+            else if (prim1.Properties != null && prim2.Properties == null)\r
+            {\r
+                return -1;\r
+            }\r
+            else if (prim1.Properties == null && prim2.Properties != null)\r
+            {\r
+                return 1;\r
+            }\r
+\r
+            return string.Compare(prim1.Properties.Name, prim2.Properties.Name);\r
+        }\r
+        //this routine should return -1 if xy and 0 if x==y.\r
+        // for our sample we'll just use string comparison\r
+        public int Compare(Primitive prim1, Primitive prim2)\r
+        {\r
+            if (sortByName)\r
+            {\r
+                return NameCompare(prim1, prim2);\r
+            }\r
+\r
+            float dist1 = prim1.ParentID == me.LocalID ? 0 : Vector3.Distance(me.SimPosition, prim1.Position);\r
+            float dist2 = prim2.ParentID == me.LocalID ? 0 : Vector3.Distance(me.SimPosition, prim2.Position);\r
+\r
+            if (dist1 == dist2)\r
+            {\r
+                return NameCompare(prim1, prim2);\r
+            }\r
+            else\r
+            {\r
+                if (dist1 < dist2)\r
+                {\r
+                    return -1;\r
+                }\r
+                return 1;\r
+            }\r
+        }\r
+    }\r
+\r
+    public class PropertiesQueue : IDisposable\r
+    {\r
+        Object sync = new Object();\r
+        RadegastInstance instance;\r
+        System.Timers.Timer qTimer;\r
+        Queue<Primitive> props = new Queue<Primitive>();\r
+\r
+        public delegate void TickCallback(int remaining);\r
+        public event TickCallback OnTick;\r
+\r
+        public PropertiesQueue(RadegastInstance instance)\r
+        {\r
+            this.instance = instance;\r
+            qTimer = new System.Timers.Timer(2500);\r
+            qTimer.Enabled = true;\r
+            qTimer.Elapsed += new ElapsedEventHandler(qTimer_Elapsed);\r
+        }\r
+\r
+        public void RequestProps(Primitive prim)\r
+        {\r
+            lock (sync)\r
+            {\r
+                if (!props.Contains(prim))\r
+                {\r
+                    props.Enqueue(prim);\r
+                }\r
+            }\r
+        }\r
+\r
+        void qTimer_Elapsed(object sender, ElapsedEventArgs e)\r
+        {\r
+            lock (sync)\r
+            {\r
+                for (int i = 0; i < 25 && props.Count > 0; i++)\r
+                {\r
+                    Primitive prim = props.Dequeue();\r
+                    if (prim.ParentID == 0)\r
+                    {\r
+                        instance.Client.Objects.RequestObjectPropertiesFamily(\r
+                            instance.Client.Network.CurrentSim, prim.ID, true);\r
+                    }\r
+                    else\r
+                    {\r
+                        instance.Client.Objects.SelectObject(instance.Client.Network.CurrentSim,\r
+                            prim.LocalID, true);\r
+                    }\r
+                }\r
+\r
+                if (OnTick != null)\r
+                {\r
+                    OnTick(props.Count);\r
+                }\r
+            }\r
+        }\r
+\r
+        public void Dispose()\r
+        {\r
+            if (qTimer != null)\r
+            {\r
+                qTimer.Elapsed -= new ElapsedEventHandler(qTimer_Elapsed);\r
+                qTimer.Enabled = false;\r
+                qTimer = null;\r
+            }\r
+            props = null;\r
+            instance = null;\r
+        }\r
+    }\r
+\r
 }
\ No newline at end of file