OSDN Git Service

RAD-490: Add a Automaticly Accept Dialog Function
[radegast/radegast.git] / Radegast / GUI / Consoles / TabsConsole.cs
index 110b68f..943ae7e 100644 (file)
@@ -1,6 +1,6 @@
 // 
 // Radegast Metaverse Client
-// Copyright (c) 2009-2010, 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; } }
@@ -153,6 +154,8 @@ namespace Radegast
             client.Self.LoadURL += new EventHandler<LoadUrlEventArgs>(Self_LoadURL);
             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)
@@ -162,6 +165,8 @@ namespace Radegast
             client.Self.LoadURL -= new EventHandler<LoadUrlEventArgs>(Self_LoadURL);
             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)
@@ -181,7 +186,6 @@ namespace Radegast
             netcom.ClientLoginStatus += new EventHandler<LoginProgressEventArgs>(netcom_ClientLoginStatus);
             netcom.ClientLoggedOut += new EventHandler(netcom_ClientLoggedOut);
             netcom.ClientDisconnected += new EventHandler<DisconnectedEventArgs>(netcom_ClientDisconnected);
-            netcom.ChatReceived += new EventHandler<ChatEventArgs>(netcom_ChatReceived);
             netcom.ChatSent += new EventHandler<ChatSentEventArgs>(netcom_ChatSent);
             netcom.AlertMessageReceived += new EventHandler<AlertMessageEventArgs>(netcom_AlertMessageReceived);
             netcom.InstantMessageReceived += new EventHandler<InstantMessageEventArgs>(netcom_InstantMessageReceived);
@@ -192,20 +196,83 @@ namespace Radegast
             netcom.ClientLoginStatus -= new EventHandler<LoginProgressEventArgs>(netcom_ClientLoginStatus);
             netcom.ClientLoggedOut -= new EventHandler(netcom_ClientLoggedOut);
             netcom.ClientDisconnected -= new EventHandler<DisconnectedEventArgs>(netcom_ClientDisconnected);
-            netcom.ChatReceived -= new EventHandler<ChatEventArgs>(netcom_ChatReceived);
             netcom.ChatSent -= new EventHandler<ChatSentEventArgs>(netcom_ChatSent);
             netcom.AlertMessageReceived -= new EventHandler<AlertMessageEventArgs>(netcom_AlertMessageReceived);
             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)
+            {
+                BeginInvoke(new MethodInvoker(() => Network_EventQueueRunning(sender, e)));
+                return;
+            }
+
+            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));
         }
 
         void Self_ScriptQuestion(object sender, ScriptQuestionEventArgs e)
         {
-            instance.MainForm.AddNotification(new ntfPermissions(instance, e.Simulator, e.TaskID, e.ItemID, e.ObjectName, e.ObjectOwnerName, e.Questions));
+            // Is this object muted
+            if (null != client.Self.MuteList.Find(m => (m.Type == MuteType.Object && m.ID == e.TaskID) // muted object by id
+                || (m.Type == MuteType.ByName && m.Name == e.ObjectName) // object muted by name
+                )) return;
+
+            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)
@@ -219,8 +286,6 @@ namespace Radegast
                 DisplayNotificationInChat("Logged in as " + netcom.LoginOptions.FullName + ".", ChatBufferTextStyle.StatusDarkBlue);
                 DisplayNotificationInChat("Login reply: " + e.Message, ChatBufferTextStyle.StatusDarkBlue);
 
-                InitializeOnlineTabs();
-
                 if (tabs.ContainsKey("login"))
                 {
                     if (selectedTab.Name == "login")
@@ -277,20 +342,34 @@ namespace Radegast
             tabs["chat"].Highlight();
         }
 
-        private void netcom_ChatReceived(object sender, ChatEventArgs e)
-        {
-            if (string.IsNullOrEmpty(e.Message)) return;
-
-            tabs["chat"].Highlight();
-        }
-
         void Self_LoadURL(object sender, LoadUrlEventArgs e)
         {
+            // Is the object or the owner 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
+                || (m.Type == MuteType.Resident && m.ID == e.OwnerID) // object's owner muted
+                )) return;
+
             instance.MainForm.AddNotification(new ntfLoadURL(instance, e));
         }
 
         private void netcom_InstantMessageReceived(object sender, InstantMessageEventArgs e)
         {
+            // 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:
@@ -309,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);
@@ -317,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);
@@ -361,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;
@@ -385,12 +478,39 @@ namespace Radegast
                     break;
 
                 case InstantMessageDialog.GroupNotice:
+                    // Is this group muted?
+                    if (null != client.Self.MuteList.Find(me => me.Type == MuteType.Group && me.ID == e.IM.FromAgentID)) break;
+
                     instance.MainForm.AddNotification(new ntfGroupNotice(instance, e.IM));
                     break;
 
                 case InstantMessageDialog.InventoryOffered:
+                    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:
-                    instance.MainForm.AddNotification(new ntfInventoryOffer(instance, e.IM));
+                    // Is the object muted by name?
+                    if (null != client.Self.MuteList.Find(me => me.Type == MuteType.ByName && me.Name == e.IM.FromAgentName)) break;
+
+                    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;
             }
         }
@@ -400,7 +520,7 @@ namespace Radegast
         /// </summary>
         public void SelectDefaultTab()
         {
-            if (TabExists("chat"))
+            if (IsHandleCreated && TabExists("chat"))
                 tabs["chat"].Select();
         }
 
@@ -442,6 +562,8 @@ namespace Radegast
             {
                 ChatBufferItem line = new ChatBufferItem(
                     DateTime.Now,
+                    string.Empty,
+                    UUID.Zero,
                     msg,
                     style
                 );
@@ -466,20 +588,80 @@ namespace Radegast
 
         private void HandleIMFromObject(InstantMessageEventArgs e)
         {
+            // Is the object or the owner muted?
+            if (null != client.Self.MuteList.Find(m => (m.Type == MuteType.Object && m.ID == e.IM.IMSessionID) // muted object by id 
+                || (m.Type == MuteType.ByName && m.Name == e.IM.FromAgentName) // object muted by name
+                || (m.Type == MuteType.Resident && m.ID == e.IM.FromAgentID) // object's owner muted
+                )) return;
+
             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;
             }
+            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)
@@ -487,29 +669,57 @@ namespace Radegast
             if (TabExists(e.IM.IMSessionID.ToString()))
             {
                 RadegastTab tab = tabs[e.IM.IMSessionID.ToString()];
-                if (!tab.Selected) tab.Highlight();
+                tab.Highlight();
                 return;
             }
 
-            ConferenceIMTabWindow imTab = AddConferenceIMTab(e);
+            instance.MediaManager.PlayUISound(UISounds.IM);
+
+            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)
         {
+            // Ignore group IM from a muted group
+            if (null != client.Self.MuteList.Find(me => me.Type == MuteType.Group && (me.ID == e.IM.IMSessionID || me.ID == e.IM.FromAgentID))) return;
+
             if (TabExists(e.IM.IMSessionID.ToString()))
             {
                 RadegastTab tab = tabs[e.IM.IMSessionID.ToString()];
-                if (!tab.Selected) tab.Highlight();
+                tab.Highlight();
                 return;
             }
 
-            GroupIMTabWindow imTab = AddGroupIMTab(e);
+            instance.MediaManager.PlayUISound(UISounds.IM);
+
+            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);
@@ -650,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);
@@ -668,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;
         }
 
@@ -696,8 +922,12 @@ namespace Radegast
 
             selectedTab = tab;
 
-            tbtnCloseTab.Enabled = tab.AllowClose || tab.AllowHide;
-            owner.AcceptButton = tab.DefaultControlButton;
+            tbtnCloseTab.Enabled = !tab.Merged && (tab.AllowClose || tab.AllowHide);
+
+            if (owner != null)
+            {
+                owner.AcceptButton = tab.DefaultControlButton;
+            }
 
             if (OnTabSelected != null)
             {
@@ -877,7 +1107,6 @@ namespace Radegast
 
             RadegastTab tab = AddTab(session.ToString(), "IM: " + targetName, imTab);
             imTab.SelectIMInput();
-            tab.Highlight();
 
             return imTab;
         }
@@ -892,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);
@@ -910,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);
@@ -941,14 +1148,6 @@ namespace Radegast
             return msTab;
         }
 
-        public AttachmentTab AddATTab(Avatar avatar)
-        {
-            AttachmentTab atTab = new AttachmentTab(instance, avatar);
-
-            RadegastTab tab = AddTab("AT: " + avatar.Name, "AT: " + avatar.Name, atTab);
-            return atTab;
-        }
-
         public AnimTab AddAnimTab(Avatar avatar)
         {
             AnimTab animTab = new AnimTab(instance, avatar);
@@ -1033,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();
@@ -1046,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);
 
@@ -1057,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();