OSDN Git Service

Added option to disable speech for objects, inventory and friends
[radegast/radegast.git] / plugins / Radegast.Plugin.Speech / RadSpeech / Conversation / Control.cs
index 480c7a3..ad58a8c 100644 (file)
@@ -7,6 +7,13 @@ using Radegast;
 using System.Text.RegularExpressions;\r
 using System.Net;\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
 \r
 namespace RadegastSpeech.Conversation\r
 {\r
@@ -41,7 +48,7 @@ namespace RadegastSpeech.Conversation
         {\r
             // Initialize the index to conversations and the list of pending interruptions.\r
             interruptions = new LinkedList<Mode>();\r
-            conversations = new Dictionary<string,Mode>();\r
+            conversations = new Dictionary<string, Mode>();\r
         }\r
 \r
         internal override void Start()\r
@@ -63,8 +70,8 @@ namespace RadegastSpeech.Conversation
             // Automatically handle notifications (blue dialogs)\r
             Notification.OnNotificationDisplayed +=\r
                 new Notification.NotificationCallback(OnNotificationDisplayed);\r
-//            Notification.OnNotificationClosed +=\r
-//                new Notification.NotificationCallback(OnNotificationClosed);\r
+            //            Notification.OnNotificationClosed +=\r
+            //                new Notification.NotificationCallback(OnNotificationClosed);\r
 \r
             // Announce connect and disconnect.\r
             control.instance.Netcom.ClientConnected +=\r
@@ -95,14 +102,30 @@ namespace RadegastSpeech.Conversation
             control.instance.Client.Self.IM +=\r
                 new EventHandler<InstantMessageEventArgs>(OnInstantMessage);\r
 \r
+            // Outgoing IMs\r
+            control.instance.Netcom.InstantMessageSent += new EventHandler<Radegast.Netcom.InstantMessageSentEventArgs>(Netcom_InstantMessageSent);\r
+\r
             // Watch for global keys\r
             control.instance.MainForm.KeyUp += new KeyEventHandler(MainForm_KeyUp);\r
 \r
+            // System messages in chat window\r
+            control.instance.TabConsole.OnChatNotification += new TabsConsole.ChatNotificationCallback(TabConsole_OnChatNotification);\r
+\r
             control.listener.ActivateGrammar(CONVGRAMMAR);\r
 \r
         }\r
 \r
         /// <summary>\r
+        /// Say various notifications that come in the chat\r
+        /// </summary>\r
+        /// <param name="sender">Message sender</param>\r
+        /// <param name="e">Event args</param>\r
+        void TabConsole_OnChatNotification(object sender, ChatNotificationEventArgs e)\r
+        {\r
+            Talker.Say(e.Message);\r
+        }\r
+\r
+        /// <summary>\r
         /// Watch for global function keys.\r
         /// </summary>\r
         /// <param name="sender"></param>\r
@@ -139,11 +162,11 @@ namespace RadegastSpeech.Conversation
                     Talker.SayMore("Connecting to region");\r
                     return;\r
 \r
-               case LoginStatus.Success:\r
+                case LoginStatus.Success:\r
                     LoginName = control.instance.Netcom.LoginOptions.FullName;\r
-                    Talker.SayMore("Logged in as " + LoginName);\r
-                    if (friends != null)\r
-                        friends.Announce = true;\r
+                    //Talker.SayMore("Logged in as " + LoginName);\r
+                    //if (friends != null)\r
+                    //    friends.Announce = true;\r
                     return;\r
 \r
                 case LoginStatus.Failed:\r
@@ -163,10 +186,17 @@ namespace RadegastSpeech.Conversation
         /// <param name="e"></param>\r
         void OnTabChange(object sender, TabEventArgs e)\r
         {\r
-            System.Windows.Forms.Control sTabControl = e.Tab.Control;\r
+            ActivateConversationFromTab(e.Tab);\r
+        }\r
 \r
-            if (sTabControl is InventoryConsole)\r
+        public void ActivateConversationFromTab(RadegastTab Tab)\r
+        {\r
+            System.Windows.Forms.Control sTabControl = Tab.Control;\r
+\r
+            if (sTabControl is InventoryConsole && control.config["enabled_for_inventory"])\r
+            {\r
                 SelectConversation(inventory);\r
+            }\r
             else if (sTabControl is ChatConsole)\r
             {\r
                 if (chat == null)\r
@@ -177,22 +207,31 @@ namespace RadegastSpeech.Conversation
                 }\r
                 SelectConversation(chat);\r
             }\r
-            else if (sTabControl is FriendsConsole)\r
+            else if (sTabControl is FriendsConsole && control.config["enabled_for_friends"])\r
+            {\r
                 SelectConversation(friends);\r
+            }\r
             else if (sTabControl is VoiceConsole)\r
+            {\r
                 SelectConversation(voice);\r
+            }\r
             else if (sTabControl is GroupIMTabWindow)\r
             {\r
                 GroupIMTabWindow tab = (GroupIMTabWindow)sTabControl;\r
                 SelectConversation(\r
                     control.instance.Groups[tab.SessionId].Name);\r
             }\r
+            else if (sTabControl is ConferenceIMTabWindow)\r
+            {\r
+                ConferenceIMTabWindow tab = (ConferenceIMTabWindow)sTabControl;\r
+                SelectConversation(tab.SessionName);\r
+            }\r
             else if (sTabControl is IMTabWindow)\r
             {\r
                 IMTabWindow tab = (IMTabWindow)sTabControl;\r
                 SelectConversation(tab.TargetName);\r
             }\r
-            else if (sTabControl is ObjectsConsole)\r
+            else if (sTabControl is ObjectsConsole && control.config["enabled_for_objects"])\r
             {\r
                 SelectConversation(surroundings);\r
             }\r
@@ -206,38 +245,55 @@ namespace RadegastSpeech.Conversation
         /// <param name="e"></param>\r
         void TabConsole_OnTabAdded(object sender, TabEventArgs e)\r
         {\r
-            System.Windows.Forms.Control sTabControl = e.Tab.Control;\r
+            CreateConversationFromTab(e.Tab, true);\r
+        }\r
+\r
+        public void CreateConversationFromTab(RadegastTab Tab, bool selectConversation)\r
+        {\r
+            System.Windows.Forms.Control sTabControl = Tab.Control;\r
 \r
             Mode newConv = null;\r
 \r
             // Create a conversation on first appearance of its tab.\r
-            if (sTabControl is InventoryConsole)\r
+            if (sTabControl is InventoryConsole && control.config["enabled_for_inventory"])\r
+            {\r
                 newConv = inventory = new Closet(control);\r
+            }\r
             else if (sTabControl is ChatConsole)\r
             {\r
                 if (chat != null) return;\r
                 newConv = chat = new Chat(control);\r
             }\r
-            else if (sTabControl is FriendsConsole)\r
+            else if (sTabControl is FriendsConsole && control.config["enabled_for_friends"])\r
+            {\r
                 newConv = friends = new Friends(control);\r
+            }\r
             else if (sTabControl is VoiceConsole)\r
+            {\r
                 newConv = voice = new Voice(control);\r
+            }\r
             else if (sTabControl is GroupIMTabWindow)\r
             {\r
                 GroupIMTabWindow tab = (GroupIMTabWindow)sTabControl;\r
                 AddConversation(new GroupIMSession(control, tab.SessionId));\r
                 return;\r
             }\r
+            else if (sTabControl is ConferenceIMTabWindow)\r
+            {\r
+                ConferenceIMTabWindow tab = (ConferenceIMTabWindow)sTabControl;\r
+                AddConversation(new ConferenceIMSession(control, tab.SessionId, tab.SessionName));\r
+                return;\r
+            }\r
             else if (sTabControl is IMTabWindow)\r
             {\r
                 IMTabWindow tab = (IMTabWindow)sTabControl;\r
                 AddConversation(new SingleIMSession(control, tab.TargetName, tab.TargetId, tab.SessionId));\r
                 return;\r
             }\r
-            else if (sTabControl is ObjectsConsole)\r
+            else if (sTabControl is ObjectsConsole && control.config["enabled_for_objects"])\r
             {\r
-                surroundings = new Surroundings( control );\r
-                AddConversation( surroundings );\r
+                surroundings = new Surroundings(control);\r
+                AddConversation(surroundings);\r
             }\r
 \r
             // If a conversation was created, switch to it.\r
@@ -245,7 +301,7 @@ namespace RadegastSpeech.Conversation
             {\r
                 AddConversation(newConv);\r
                 // Select CHAT as soon as it is created.\r
-                if (sTabControl is ChatConsole)\r
+                if (selectConversation && sTabControl is ChatConsole)\r
                     SelectConversation(newConv);\r
             }\r
         }\r
@@ -259,13 +315,15 @@ namespace RadegastSpeech.Conversation
         {\r
             System.Windows.Forms.Control sTabControl = e.Tab.Control;\r
             if (sTabControl is InventoryConsole)\r
-                RemoveConversation( inventory.Title );\r
+                RemoveConversation(inventory.Title);\r
             else if (sTabControl is ChatConsole)\r
                 RemoveConversation(chat.Title);\r
             else if (sTabControl is FriendsConsole)\r
                 RemoveConversation(friends.Title);\r
             else if (sTabControl is VoiceConsole)\r
                 RemoveConversation(voice.Title);\r
+            else if (sTabControl is ConferenceIMTabWindow)\r
+                RemoveConversation(((ConferenceIMTabWindow)e.Tab.Control).SessionName);\r
             else if (sTabControl is GroupIMTabWindow ||\r
                      sTabControl is IMTabWindow)\r
                 RemoveConversation(sTabControl.Name);  // TODO wrong name\r
@@ -274,6 +332,12 @@ namespace RadegastSpeech.Conversation
 \r
         internal override void Shutdown()\r
         {\r
+            if (chat != null)\r
+            {\r
+                chat.Dispose();\r
+                chat = null;\r
+            }\r
+\r
             // Automatically handle notifications (blue dialogs)\r
             Notification.OnNotificationDisplayed -=\r
                 new Notification.NotificationCallback(OnNotificationDisplayed);\r
@@ -304,9 +368,14 @@ namespace RadegastSpeech.Conversation
                 new TabsConsole.TabCallback(OnTabChange);\r
 \r
             // Handle Instant Messages too\r
-            control.instance.Client.Self.IM +=\r
-                new EventHandler<InstantMessageEventArgs>(OnInstantMessage);  \r
+            control.instance.Client.Self.IM -=\r
+                new EventHandler<InstantMessageEventArgs>(OnInstantMessage);\r
+\r
+            // Outgoing IMs\r
+            control.instance.Netcom.InstantMessageSent -= new EventHandler<Radegast.Netcom.InstantMessageSentEventArgs>(Netcom_InstantMessageSent);\r
 \r
+            // System notifications in chat\r
+            control.instance.TabConsole.OnChatNotification -= new TabsConsole.ChatNotificationCallback(TabConsole_OnChatNotification);\r
 \r
             control.listener.DeactivateGrammar(CONVGRAMMAR);\r
 \r
@@ -348,7 +417,7 @@ namespace RadegastSpeech.Conversation
         /// <summary>\r
         /// Finish an interruption and resume normal conversation\r
         /// </summary>\r
-        internal void FinishInterruption( Mode m )\r
+        internal void FinishInterruption(Mode m)\r
         {\r
             lock (interruptions)\r
             {\r
@@ -370,7 +439,7 @@ namespace RadegastSpeech.Conversation
                 }\r
             }\r
         }\r
\r
+\r
         private void Network_ClientConnected(object sender, EventArgs e)\r
         {\r
             Talker.Say("You are connected.", Talk.BeepType.Good);\r
@@ -471,7 +540,7 @@ namespace RadegastSpeech.Conversation
             }\r
             return true;\r
         }\r
-        \r
+\r
         /// <summary>\r
         /// Dispatch recognized text to appropriate conversation.\r
         /// </summary>\r
@@ -490,7 +559,7 @@ namespace RadegastSpeech.Conversation
         {\r
             if (c == null)\r
             {\r
-                Talker.Say("Trying to start non-existant conversation", Talk.BeepType.Bad );\r
+                Logger.Log("Trying to start non-existant conversation", Helpers.LogLevel.Warning);\r
                 return;\r
             }\r
             // Avoid multiple starts.\r
@@ -588,11 +657,11 @@ namespace RadegastSpeech.Conversation
         internal void ChangeFocus(Mode toThis)\r
         {\r
             currentMode = toThis;\r
-             if (currentMode != null)\r
+            if (currentMode != null)\r
                 currentMode.Start();\r
         }\r
 \r
\r
+\r
         /// <summary>\r
         /// Event handler for new blue dialog boxes.\r
         /// </summary>\r
@@ -600,71 +669,102 @@ namespace RadegastSpeech.Conversation
         /// <param name="e"></param>\r
         void OnNotificationDisplayed(object sender, NotificationEventArgs e)\r
         {\r
-            AddInterruption(new Conversation.BlueMenu(control,e));\r
+            AddInterruption(new Conversation.BlueMenu(control, e));\r
         }\r
 \r
         /// <summary>\r
+        /// Event handler for outgoing IMs\r
+        /// </summary>\r
+        /// <param name="sender"></param>\r
+        /// <param name="e"></param>\r
+        void Netcom_InstantMessageSent(object sender, Radegast.Netcom.InstantMessageSentEventArgs e)\r
+        {\r
+            // Message to an individual\r
+            Conversation.IMSession sess = (IMSession)control.converse.GetConversation(control.instance.Names.Get(e.TargetID, true));\r
+            if (sess != null)\r
+                sess.OnMessage(Client.Self.AgentID, Client.Self.Name, e.Message);\r
+        }\r
+\r
+\r
+        /// <summary>\r
         /// Handle Instant Messages\r
         /// </summary>\r
         /// <param name="im"></param>\r
         /// <param name="simulator"></param>\r
         void OnInstantMessage(object sender, InstantMessageEventArgs e)\r
         {\r
-            Conversation.IMSession sess;\r
-            string groupName;\r
-\r
-            // All sorts of things come in as a instant messages. For actual messages\r
-            // we need to match them up with an existing Conversation.  IM Conversations\r
-            // are keyed by the name of the group or individual involved.\r
-            switch (e.IM.Dialog)\r
-            {\r
-                case InstantMessageDialog.MessageFromAgent:\r
-                    if (control.instance.Groups.ContainsKey(e.IM.IMSessionID))\r
-                    {\r
-                        // Message from a group member\r
-                        groupName = control.instance.Groups[e.IM.IMSessionID].Name;\r
-                        sess = (IMSession)control.converse.GetConversation(groupName);\r
-                        if (sess!=null)\r
-                            sess.OnMessage( e.IM.FromAgentID, e.IM.FromAgentName, e.IM.Message );\r
-                    }\r
-                    else if (e.IM.BinaryBucket.Length >= 2)\r
-                    {\r
-                        // Ad-hoc friend conference\r
-                        // TODO this is probably the wrong name\r
-                        sess = (IMSession)control.converse.GetConversation(e.IM.FromAgentName);\r
-                        if (sess != null)\r
-                            sess.OnMessage(e.IM.FromAgentID, e.IM.FromAgentName, e.IM.Message);\r
-                    }\r
-                    else if (e.IM.FromAgentName == "Second Life")\r
-                    {\r
-                        Talker.Say("Second Life says "+ e.IM.Message);\r
-                    }\r
-                    else\r
+            WorkPool.QueueUserWorkItem(sync =>\r
+                {\r
+                    Thread.Sleep(100); // Give tab a chance to show up\r
+                    Conversation.IMSession sess = null;\r
+                    string groupName;\r
+\r
+                    // All sorts of things come in as a instant messages. For actual messages\r
+                    // we need to match them up with an existing Conversation.  IM Conversations\r
+                    // are keyed by the name of the group or individual involved.\r
+                    switch (e.IM.Dialog)\r
                     {\r
-                        // Message from an individual\r
-                        sess = (IMSession)control.converse.GetConversation(e.IM.FromAgentName); \r
-                        if (sess != null)\r
-                            sess.OnMessage(e.IM.FromAgentID, e.IM.FromAgentName, e.IM.Message);\r
+                        case InstantMessageDialog.MessageFromAgent:\r
+                            if (control.instance.Groups.ContainsKey(e.IM.IMSessionID))\r
+                            {\r
+                                // Message from a group member\r
+                                groupName = control.instance.Groups[e.IM.IMSessionID].Name;\r
+                                sess = (IMSession)control.converse.GetConversation(groupName);\r
+                                if (sess != null)\r
+                                    sess.OnMessage(e.IM.FromAgentID, e.IM.FromAgentName, e.IM.Message);\r
+                                else\r
+                                    Talker.Say(e.IM.FromAgentName + ", " + e.IM.Message);\r
+                            }\r
+                            else if (e.IM.BinaryBucket.Length >= 2)\r
+                            {\r
+                                // Ad-hoc friend conference\r
+                                sess = (IMSession)control.converse.GetConversation(Utils.BytesToString(e.IM.BinaryBucket));\r
+                                if (sess != null)\r
+                                    sess.OnMessage(e.IM.FromAgentID, e.IM.FromAgentName, e.IM.Message);\r
+                                else\r
+                                    Talker.Say(e.IM.FromAgentName + ", " + e.IM.Message);\r
+                            }\r
+                            else if (e.IM.FromAgentName == "Second Life")\r
+                            {\r
+                                Talker.Say("Second Life says " + e.IM.Message);\r
+                            }\r
+                            else\r
+                            {\r
+                                // Message from an individual\r
+                                sess = (IMSession)control.converse.GetConversation(e.IM.FromAgentName);\r
+                                if (sess != null)\r
+                                    sess.OnMessage(e.IM.FromAgentID, e.IM.FromAgentName, e.IM.Message);\r
+                                else\r
+                                    Talker.Say(e.IM.FromAgentName + ", " + e.IM.Message);\r
+                            }\r
+                            break;\r
+\r
+                        case InstantMessageDialog.SessionSend:\r
+                            if (control.instance.Groups.ContainsKey(e.IM.IMSessionID))\r
+                            {\r
+                                // Message from a group member\r
+                                groupName = control.instance.Groups[e.IM.IMSessionID].Name;\r
+                                sess = (IMSession)control.converse.GetConversation(groupName);\r
+                            }\r
+                            else if (e.IM.BinaryBucket.Length >= 2) // ad hoc friends conference\r
+                            {\r
+                                sess = (IMSession)control.converse.GetConversation(Utils.BytesToString(e.IM.BinaryBucket));\r
+                            }\r
+\r
+                            if (sess != null)\r
+                                sess.OnMessage(e.IM.FromAgentID, e.IM.FromAgentName, e.IM.Message);\r
+                            break;\r
+\r
+                        case InstantMessageDialog.FriendshipOffered:\r
+                            Talker.Say(e.IM.FromAgentName + " is offering friendship.");\r
+                            break;\r
+\r
+                        default:\r
+                            break;\r
                     }\r
-                    break;\r
-\r
-                case InstantMessageDialog.SessionSend:\r
-                    // Message from a group member\r
-                    groupName = control.instance.Groups[e.IM.IMSessionID].Name;\r
-                    sess = (IMSession)control.converse.GetConversation(groupName);\r
-                    if (sess != null)\r
-                        sess.OnMessage(e.IM.FromAgentID, e.IM.FromAgentName, e.IM.Message);\r
-                    break;\r
-\r
-                case InstantMessageDialog.FriendshipOffered:\r
-                    Talker.Say(e.IM.FromAgentName + " is offering friendship.");\r
-                    break;\r
-\r
-                default:\r
-                    break;\r
-            }\r
+                }\r
+            );\r
 \r
         }\r
     }\r
 }\r
-\r