OSDN Git Service

RAD-490: Add a Automaticly Accept Dialog Function
[radegast/radegast.git] / Radegast / GUI / Consoles / TabsConsole.cs
index 696469a..943ae7e 100644 (file)
@@ -1,6 +1,6 @@
 // 
 // Radegast Metaverse Client
-// Copyright (c) 2009-2011, Radegast Development Team
+// Copyright (c) 2009-2014, Radegast Development Team
 // All rights reserved.
 // 
 // Redistribution and use in source and binary forms, with or without
@@ -108,6 +108,7 @@ namespace Radegast
         private GridClient client { get { return instance.Client; } }
         private RadegastNetcom netcom { get { return instance.Netcom; } }
         private ChatTextManager mainChatManger;
+        public ChatTextManager MainChatManger { get { return mainChatManger; } }
 
         private Dictionary<string, RadegastTab> tabs = new Dictionary<string, RadegastTab>();
         public Dictionary<string, RadegastTab> Tabs { get { return tabs; } }
@@ -154,6 +155,7 @@ namespace Radegast
             client.Self.SetDisplayNameReply += new EventHandler<SetDisplayNameReplyEventArgs>(Self_SetDisplayNameReply);
             client.Avatars.DisplayNameUpdate += new EventHandler<DisplayNameUpdateEventArgs>(Avatars_DisplayNameUpdate);
             client.Network.EventQueueRunning += new EventHandler<EventQueueRunningEventArgs>(Network_EventQueueRunning);
+            client.Network.RegisterCallback(OpenMetaverse.Packets.PacketType.ScriptTeleportRequest, ScriptTeleportRequestHandler);
         }
 
         private void UnregisterClientEvents(GridClient client)
@@ -164,6 +166,7 @@ namespace Radegast
             client.Self.SetDisplayNameReply -= new EventHandler<SetDisplayNameReplyEventArgs>(Self_SetDisplayNameReply);
             client.Avatars.DisplayNameUpdate -= new EventHandler<DisplayNameUpdateEventArgs>(Avatars_DisplayNameUpdate);
             client.Network.EventQueueRunning -= new EventHandler<EventQueueRunningEventArgs>(Network_EventQueueRunning);
+            client.Network.UnregisterCallback(OpenMetaverse.Packets.PacketType.ScriptTeleportRequest, ScriptTeleportRequestHandler);
         }
 
         void instance_ClientChanged(object sender, ClientChangedEventArgs e)
@@ -198,6 +201,27 @@ namespace Radegast
             netcom.InstantMessageReceived -= new EventHandler<InstantMessageEventArgs>(netcom_InstantMessageReceived);
         }
 
+        void ScriptTeleportRequestHandler(object sender, PacketReceivedEventArgs e)
+        {
+            if (InvokeRequired)
+            {
+                if (IsHandleCreated || !instance.MonoRuntime)
+                    BeginInvoke(new MethodInvoker(() => ScriptTeleportRequestHandler(sender, e)));
+                return;
+            }
+
+            var msg = (OpenMetaverse.Packets.ScriptTeleportRequestPacket)e.Packet;
+
+            if (TabExists("map"))
+            {
+                Tabs["map"].Select();
+                ((MapConsole)Tabs["map"].Control).CenterOnGlobalPos(
+                    (float)(client.Self.GlobalPosition.X - client.Self.SimPosition.X) + msg.Data.SimPosition.X,
+                    (float)(client.Self.GlobalPosition.Y - client.Self.SimPosition.Y) + msg.Data.SimPosition.Y,
+                    msg.Data.SimPosition.Z);
+            }
+        }
+
         void Network_EventQueueRunning(object sender, EventQueueRunningEventArgs e)
         {
             if (InvokeRequired)
@@ -209,17 +233,24 @@ namespace Radegast
             if (TabExists("friends")) return;
             if (e.Simulator == client.Network.CurrentSim)
             {
+                client.Self.UpdateAgentLanguage("en", true);
                 InitializeOnlineTabs();
             }
         }
 
         void Self_ScriptDialog(object sender, ScriptDialogEventArgs e)
         {
+            if (instance.MainForm.InvokeRequired)
+            {
+                instance.MainForm.BeginInvoke(new MethodInvoker(() => Self_ScriptDialog(sender, e)));
+                return;
+            }
+
             // Is this object muted
             if (null != client.Self.MuteList.Find(m => (m.Type == MuteType.Object && m.ID == e.ObjectID) // muted object by id
                 || (m.Type == MuteType.ByName && m.Name == e.ObjectName) // object muted by name
                 )) return;
-            
+
             instance.MainForm.AddNotification(new ntfScriptDialog(instance, e.Message, e.ObjectName, e.ImageID, e.ObjectID, e.FirstName, e.LastName, e.Channel, e.ButtonLabels));
         }
 
@@ -230,7 +261,18 @@ namespace Radegast
                 || (m.Type == MuteType.ByName && m.Name == e.ObjectName) // object muted by name
                 )) return;
 
-            instance.MainForm.AddNotification(new ntfPermissions(instance, e.Simulator, e.TaskID, e.ItemID, e.ObjectName, e.ObjectOwnerName, e.Questions));
+            if (instance.GlobalSettings["on_script_question"] == "Auto Accept")
+            {
+                instance.Client.Self.ScriptQuestionReply(e.Simulator, e.ItemID, e.TaskID, e.Questions);
+            }
+            else if (instance.GlobalSettings["on_script_question"] == "Auto Decline")
+            {
+                instance.Client.Self.ScriptQuestionReply(e.Simulator, e.ItemID, e.TaskID, 0);
+            }
+            else
+            {
+                instance.MainForm.AddNotification(new ntfPermissions(instance, e.Simulator, e.TaskID, e.ItemID, e.ObjectName, e.ObjectOwnerName, e.Questions));
+            }
         }
 
         private void netcom_ClientLoginStatus(object sender, LoginProgressEventArgs e)
@@ -316,6 +358,18 @@ namespace Radegast
             // Messaage from someone we muted?
             if (null != client.Self.MuteList.Find(me => me.Type == MuteType.Resident && me.ID == e.IM.FromAgentID)) return;
 
+            try
+            {
+                if (instance.State.LSLHelper.ProcessIM(e))
+                {
+                    return;
+                }
+            }
+            catch (Exception ex)
+            {
+                Logger.Log("Failed executing automation action: " + ex.ToString(), Helpers.LogLevel.Warning);
+            }
+
             switch (e.IM.Dialog)
             {
                 case InstantMessageDialog.SessionSend:
@@ -334,6 +388,10 @@ namespace Radegast
                     {
                         HandleIMFromObject(e);
                     }
+                    else if (e.IM.FromAgentID == UUID.Zero)
+                    {
+                        instance.MainForm.AddNotification(new ntfGeneric(instance, e.IM.Message));
+                    }
                     else if (e.IM.GroupIM || instance.Groups.ContainsKey(e.IM.IMSessionID))
                     {
                         HandleGroupIM(e);
@@ -342,6 +400,12 @@ namespace Radegast
                     { // conference
                         HandleConferenceIM(e);
                     }
+                    else if (e.IM.IMSessionID == UUID.Zero)
+                    {
+                        String msg = string.Format("Message from {0}: {1}", instance.Names.Get(e.IM.FromAgentID, e.IM.FromAgentName), e.IM.Message);
+                        instance.MainForm.AddNotification(new ntfGeneric(instance, msg));
+                        DisplayNotificationInChat(msg);
+                    }
                     else
                     {
                         HandleIM(e);
@@ -386,6 +450,10 @@ namespace Radegast
                     }
                     break;
 
+                case InstantMessageDialog.RequestLure:
+                    instance.MainForm.AddNotification(new ntfRequestLure(instance, e.IM));
+                    break;
+
                 case InstantMessageDialog.GroupInvitation:
                     instance.MainForm.AddNotification(new ntfGroupInvitation(instance, e.IM));
                     break;
@@ -417,14 +485,32 @@ namespace Radegast
                     break;
 
                 case InstantMessageDialog.InventoryOffered:
-                    instance.MainForm.AddNotification(new ntfInventoryOffer(instance, e.IM));
+                    var ion = new ntfInventoryOffer(instance, e.IM);
+                    instance.MainForm.AddNotification(ion);
+                    if (instance.GlobalSettings["inv_auto_accept_mode"].AsInteger() == 1)
+                    {
+                        ion.btnAccept.PerformClick();
+                    }
+                    else if (instance.GlobalSettings["inv_auto_accept_mode"].AsInteger() == 2)
+                    {
+                        ion.btnDiscard.PerformClick();
+                    }
                     break;
 
                 case InstantMessageDialog.TaskInventoryOffered:
                     // Is the object muted by name?
                     if (null != client.Self.MuteList.Find(me => me.Type == MuteType.ByName && me.Name == e.IM.FromAgentName)) break;
 
-                    instance.MainForm.AddNotification(new ntfInventoryOffer(instance, e.IM));
+                    var iont = new ntfInventoryOffer(instance, e.IM);
+                    instance.MainForm.AddNotification(iont);
+                    if (instance.GlobalSettings["inv_auto_accept_mode"].AsInteger() == 1)
+                    {
+                        iont.btnAccept.PerformClick();
+                    }
+                    else if (instance.GlobalSettings["inv_auto_accept_mode"].AsInteger() == 2)
+                    {
+                        iont.btnDiscard.PerformClick();
+                    }
                     break;
             }
         }
@@ -434,7 +520,7 @@ namespace Radegast
         /// </summary>
         public void SelectDefaultTab()
         {
-            if (TabExists("chat"))
+            if (IsHandleCreated && TabExists("chat"))
                 tabs["chat"].Select();
         }
 
@@ -476,6 +562,8 @@ namespace Radegast
             {
                 ChatBufferItem line = new ChatBufferItem(
                     DateTime.Now,
+                    string.Empty,
+                    UUID.Zero,
                     msg,
                     style
                 );
@@ -509,19 +597,71 @@ namespace Radegast
             DisplayNotificationInChat(e.IM.FromAgentName + ": " + e.IM.Message);
         }
 
-        private void HandleIM(InstantMessageEventArgs e)
+        public static Control FindFocusedControl(Control control)
         {
-            if (TabExists(e.IM.IMSessionID.ToString()))
+            var container = control as ContainerControl;
+            while (container != null)
             {
-                RadegastTab tab = tabs[e.IM.IMSessionID.ToString()];
-                if (!tab.Selected) tab.Highlight();
-                return;
+                control = container.ActiveControl;
+                container = control as ContainerControl;
             }
-            
-            instance.MediaManager.PlayUISound(UISounds.IM);
+            return control;
+        }
 
-            IMTabWindow imTab = AddIMTab(e);
-            tabs[e.IM.IMSessionID.ToString()].Highlight();
+        /// <summary>
+        /// Creates new IM tab if needed
+        /// </summary>
+        /// <param name="agentID">IM session with agentID</param>
+        /// <param name="label">Tab label</param>
+        /// <param name="makeActive">Should tab be selected and focused</param>
+        /// <returns>True if there was an existing IM tab, false if it was created</returns>
+        public bool ShowIMTab(UUID agentID, string label, bool makeActive)
+        {
+            if (instance.TabConsole.TabExists((client.Self.AgentID ^ agentID).ToString()))
+            {
+                if (makeActive)
+                {
+                    instance.TabConsole.SelectTab((client.Self.AgentID ^ agentID).ToString());
+                }
+                return false;
+            }
+
+            if (makeActive)
+            {
+                instance.MediaManager.PlayUISound(UISounds.IMWindow);
+            }
+            else
+            {
+                instance.MediaManager.PlayUISound(UISounds.IM);
+            }
+
+            Control active = FindFocusedControl(instance.MainForm);
+
+            instance.TabConsole.AddIMTab(agentID, client.Self.AgentID ^ agentID, label);
+
+            if (makeActive)
+            {
+                instance.TabConsole.SelectTab((client.Self.AgentID ^ agentID).ToString());
+            }
+            else if (active != null)
+            {
+                active.Focus();
+            }
+
+            return true;
+        }
+
+        private void HandleIM(InstantMessageEventArgs e)
+        {
+            bool isNew = ShowIMTab(e.IM.FromAgentID, e.IM.FromAgentName, false);
+            if (!TabExists(e.IM.IMSessionID.ToString())) return; // this should now exist. sanity check anyway
+            RadegastTab tab = tabs[e.IM.IMSessionID.ToString()];
+            tab.Highlight();
+
+            if (isNew)
+            {
+                ((IMTabWindow)tab.Control).TextManager.ProcessIM(e);
+            }
         }
 
         private void HandleConferenceIM(InstantMessageEventArgs e)
@@ -529,14 +669,22 @@ namespace Radegast
             if (TabExists(e.IM.IMSessionID.ToString()))
             {
                 RadegastTab tab = tabs[e.IM.IMSessionID.ToString()];
-                if (!tab.Selected) tab.Highlight();
+                tab.Highlight();
                 return;
             }
 
             instance.MediaManager.PlayUISound(UISounds.IM);
 
-            ConferenceIMTabWindow imTab = AddConferenceIMTab(e);
+            Control active = FindFocusedControl(instance.MainForm);
+
+            ConferenceIMTabWindow imTab = AddConferenceIMTab(e.IM.IMSessionID, Utils.BytesToString(e.IM.BinaryBucket));
             tabs[e.IM.IMSessionID.ToString()].Highlight();
+            imTab.TextManager.ProcessIM(e);
+
+            if (active != null)
+            {
+                active.Focus();
+            }
         }
 
         private void HandleGroupIM(InstantMessageEventArgs e)
@@ -547,18 +695,31 @@ namespace Radegast
             if (TabExists(e.IM.IMSessionID.ToString()))
             {
                 RadegastTab tab = tabs[e.IM.IMSessionID.ToString()];
-                if (!tab.Selected) tab.Highlight();
+                tab.Highlight();
                 return;
             }
 
             instance.MediaManager.PlayUISound(UISounds.IM);
 
-            GroupIMTabWindow imTab = AddGroupIMTab(e);
+            Control active = FindFocusedControl(instance.MainForm);
+
+            GroupIMTabWindow imTab = AddGroupIMTab(e.IM.IMSessionID, Utils.BytesToString(e.IM.BinaryBucket));
+            imTab.TextManager.ProcessIM(e);
             tabs[e.IM.IMSessionID.ToString()].Highlight();
+
+            if (active != null)
+            {
+                active.Focus();
+            }
         }
 
-        private void InitializeMainTab()
+        public void InitializeMainTab()
         {
+            if (TabExists("login"))
+            {
+                ForceCloseTab("login");
+            }
+
             LoginConsole loginConsole = new LoginConsole(instance);
 
             RadegastTab tab = AddTab("login", "Login", loginConsole);
@@ -699,6 +860,7 @@ namespace Radegast
             button.Image = null;
             button.AutoToolTip = false;
             button.Tag = name.ToLower();
+            button.AllowDrop = true;
             button.Click += new EventHandler(TabButtonClick);
 
             RadegastTab tab = new RadegastTab(instance, button, control, name.ToLower(), label);
@@ -717,6 +879,21 @@ namespace Radegast
                 catch (Exception) { }
             }
 
+            button.MouseDown += (msender, margs) =>
+            {
+                if (margs.Button == MouseButtons.Middle)
+                {
+                    if (tab.AllowClose)
+                    {
+                        tab.Close();
+                    }
+                    else if (tab.AllowHide)
+                    {
+                        tab.Hide();
+                    }
+                }
+            };
+
             return tab;
         }
 
@@ -745,8 +922,8 @@ namespace Radegast
 
             selectedTab = tab;
 
-            tbtnCloseTab.Enabled = tab.AllowClose || tab.AllowHide;
-            
+            tbtnCloseTab.Enabled = !tab.Merged && (tab.AllowClose || tab.AllowHide);
+
             if (owner != null)
             {
                 owner.AcceptButton = tab.DefaultControlButton;
@@ -930,7 +1107,6 @@ namespace Radegast
 
             RadegastTab tab = AddTab(session.ToString(), "IM: " + targetName, imTab);
             imTab.SelectIMInput();
-            tab.Highlight();
 
             return imTab;
         }
@@ -945,14 +1121,6 @@ namespace Radegast
             return imTab;
         }
 
-
-        public ConferenceIMTabWindow AddConferenceIMTab(InstantMessageEventArgs e)
-        {
-            ConferenceIMTabWindow imTab = AddConferenceIMTab(e.IM.IMSessionID, Utils.BytesToString(e.IM.BinaryBucket));
-            imTab.TextManager.ProcessIM(e);
-            return imTab;
-        }
-
         public GroupIMTabWindow AddGroupIMTab(UUID session, string name)
         {
             GroupIMTabWindow imTab = new GroupIMTabWindow(instance, session, name);
@@ -963,20 +1131,6 @@ namespace Radegast
             return imTab;
         }
 
-        public GroupIMTabWindow AddGroupIMTab(InstantMessageEventArgs e)
-        {
-            GroupIMTabWindow imTab = AddGroupIMTab(e.IM.IMSessionID, Utils.BytesToString(e.IM.BinaryBucket));
-            imTab.TextManager.ProcessIM(e);
-            return imTab;
-        }
-
-        public IMTabWindow AddIMTab(InstantMessageEventArgs e)
-        {
-            IMTabWindow imTab = AddIMTab(e.IM.FromAgentID, e.IM.IMSessionID, e.IM.FromAgentName);
-            imTab.TextManager.ProcessIM(e);
-            return imTab;
-        }
-
         public OutfitTextures AddOTTab(Avatar avatar)
         {
             OutfitTextures otTab = new OutfitTextures(instance, avatar);
@@ -1078,7 +1232,9 @@ namespace Radegast
         private void tbtnCloseTab_Click(object sender, EventArgs e)
         {
             RadegastTab tab = selectedTab;
-            if (tab.AllowClose)
+            if (tab.Merged)
+                return;
+            else if (tab.AllowClose)
                 tab.Close();
             else if (tab.AllowHide)
                 tab.Hide();
@@ -1091,6 +1247,8 @@ namespace Radegast
 
         private void ctxTabs_Opening(object sender, CancelEventArgs e)
         {
+            e.Cancel = false;
+
             Point pt = this.PointToClient(Cursor.Position);
             ToolStripItem stripItem = tstTabs.GetItemAt(pt);
 
@@ -1102,7 +1260,7 @@ namespace Radegast
             {
                 tabs[stripItem.Tag.ToString()].Select();
 
-                ctxBtnClose.Enabled = selectedTab.AllowClose || selectedTab.AllowHide;
+                ctxBtnClose.Enabled = !selectedTab.Merged && (selectedTab.AllowClose || selectedTab.AllowHide);
                 ctxBtnDetach.Enabled = selectedTab.AllowDetach;
                 ctxBtnMerge.Enabled = selectedTab.AllowMerge;
                 ctxBtnMerge.DropDown.Items.Clear();