OSDN Git Service

RAD-9: Make sure we only open one instance of user and group profiles.
[radegast/radegast.git] / Radegast / GUI / Consoles / GroupIMTabWindow.cs
1 // \r
2 // Radegast Metaverse Client\r
3 // Copyright (c) 2009, Radegast Development Team\r
4 // All rights reserved.\r
5 // \r
6 // Redistribution and use in source and binary forms, with or without\r
7 // modification, are permitted provided that the following conditions are met:\r
8 // \r
9 //     * Redistributions of source code must retain the above copyright notice,\r
10 //       this list of conditions and the following disclaimer.\r
11 //     * Redistributions in binary form must reproduce the above copyright\r
12 //       notice, this list of conditions and the following disclaimer in the\r
13 //       documentation and/or other materials provided with the distribution.\r
14 //     * Neither the name of the application "Radegast", nor the names of its\r
15 //       contributors may be used to endorse or promote products derived from\r
16 //       this software without specific prior written permission.\r
17 // \r
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
21 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
26 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
28 //\r
29 // $Id$\r
30 //\r
31 using System;\r
32 using System.Drawing;\r
33 using System.Collections.Generic;\r
34 using System.Windows.Forms;\r
35 using System.Threading;\r
36 using Radegast.Netcom;\r
37 using OpenMetaverse;\r
38 \r
39 namespace Radegast\r
40 {\r
41     public partial class GroupIMTabWindow : UserControl\r
42     {\r
43         private RadegastInstance instance;\r
44         private GridClient client { get { return instance.Client; } }\r
45         private RadegastNetcom netcom { get { return instance.Netcom; } }\r
46         private UUID session;\r
47         private IMTextManager textManager;\r
48 \r
49         ManualResetEvent WaitForSessionStart = new ManualResetEvent(false);\r
50 \r
51         public GroupIMTabWindow(RadegastInstance instance, UUID session, string sessionName)\r
52         {\r
53             InitializeComponent();\r
54             Disposed += new EventHandler(IMTabWindow_Disposed);\r
55 \r
56             this.instance = instance;\r
57             this.session = session;\r
58 \r
59             textManager = new IMTextManager(this.instance, new RichTextBoxPrinter(rtbIMText), this.session, sessionName);\r
60 \r
61             btnShow.Text = "Show";\r
62             chatSplit.Panel2Collapsed = true;\r
63 \r
64             // Callbacks\r
65             client.Self.OnGroupChatJoin += new AgentManager.GroupChatJoinedCallback(Self_OnGroupChatJoin);\r
66             client.Self.OnChatSessionMemberAdded += new AgentManager.ChatSessionMemberAddedCallback(Self_OnChatSessionMemberAdded);\r
67             client.Self.OnChatSessionMemberLeft += new AgentManager.ChatSessionMemberLeftCallback(Self_OnChatSessionMemberLeft);\r
68             client.Avatars.OnAvatarNames += new AvatarManager.AvatarNamesCallback(Avatars_OnAvatarNames);\r
69             client.Self.RequestJoinGroupChat(session);\r
70         }\r
71 \r
72         private void IMTabWindow_Disposed(object sender, EventArgs e)\r
73         {\r
74             client.Self.RequestLeaveGroupChat(session);\r
75             client.Self.OnGroupChatJoin -= new AgentManager.GroupChatJoinedCallback(Self_OnGroupChatJoin);\r
76             client.Self.OnChatSessionMemberAdded -= new AgentManager.ChatSessionMemberAddedCallback(Self_OnChatSessionMemberAdded);\r
77             client.Self.OnChatSessionMemberLeft -= new AgentManager.ChatSessionMemberLeftCallback(Self_OnChatSessionMemberLeft);\r
78             client.Avatars.OnAvatarNames -= new AvatarManager.AvatarNamesCallback(Avatars_OnAvatarNames);\r
79             CleanUp();\r
80         }\r
81 \r
82         void Avatars_OnAvatarNames(Dictionary<UUID, string> names)\r
83         {\r
84             if (InvokeRequired)\r
85             {\r
86                 BeginInvoke(new MethodInvoker(() => Avatars_OnAvatarNames(names)));\r
87                 return;\r
88             }\r
89 \r
90             Participants.BeginUpdate();\r
91 \r
92             foreach (KeyValuePair<UUID, string> kvp in names)\r
93             {\r
94                 if (Participants.Items.ContainsKey(kvp.Key.ToString()))\r
95                     Participants.Items[kvp.Key.ToString()].Text = kvp.Value;\r
96             }\r
97 \r
98             Participants.Sort();\r
99             Participants.EndUpdate();\r
100         }\r
101 \r
102         void Self_OnChatSessionMemberLeft(UUID sessionID, UUID agent_key)\r
103         {\r
104             if (sessionID == session)\r
105                 UpdateParticipantList();\r
106         }\r
107 \r
108         void Self_OnChatSessionMemberAdded(UUID sessionID, UUID agent_key)\r
109         {\r
110             if (sessionID == session)\r
111                 UpdateParticipantList();\r
112         }\r
113 \r
114         void UpdateParticipantList()\r
115         {\r
116             if (InvokeRequired)\r
117             {\r
118                 BeginInvoke(new MethodInvoker(UpdateParticipantList));\r
119                 return;\r
120             }\r
121 \r
122             Participants.BeginUpdate();\r
123             Participants.Items.Clear();\r
124 \r
125             List<ChatSessionMember> participants;\r
126             List<UUID> nameLookup = new List<UUID>();\r
127 \r
128             if (client.Self.GroupChatSessions.TryGetValue(session, out participants))\r
129             {\r
130                 ChatSessionMember[] members = participants.ToArray();\r
131                 for (int i = 0; i < members.Length; i++)\r
132                 {\r
133                     ChatSessionMember participant = members[i];\r
134                     ListViewItem item = new ListViewItem();\r
135                     item.Name = participant.AvatarKey.ToString();\r
136                     if (instance.nameCache.ContainsKey(participant.AvatarKey))\r
137                     {\r
138                         item.Text = instance.nameCache[participant.AvatarKey];\r
139                     }\r
140                     else\r
141                     {\r
142                         item.Text = RadegastInstance.INCOMPLETE_NAME;\r
143                         nameLookup.Add(participant.AvatarKey);\r
144                     }\r
145                     if (participant.IsModerator)\r
146                         item.Font = new Font(item.Font, FontStyle.Bold);\r
147                     Participants.Items.Add(item);\r
148                 }\r
149 \r
150                 if (nameLookup.Count > 0)\r
151                     client.Avatars.RequestAvatarNames(nameLookup);\r
152             }\r
153 \r
154             Participants.Sort();\r
155             Participants.EndUpdate();\r
156         }\r
157 \r
158         void Self_OnGroupChatJoin(UUID groupChatSessionID, string sessionName, UUID tmpSessionID, bool success)\r
159         {\r
160             if (groupChatSessionID != session && tmpSessionID != session)\r
161             {\r
162                 return;\r
163             }\r
164 \r
165             if (InvokeRequired)\r
166             {\r
167                 Invoke(new MethodInvoker(\r
168                     delegate()\r
169                     {\r
170                         Self_OnGroupChatJoin(groupChatSessionID, sessionName, tmpSessionID, success);\r
171                     }\r
172                     )\r
173                 );\r
174                 return;\r
175             }\r
176             if (success)\r
177             {\r
178                 textManager.TextPrinter.PrintTextLine("Join Group Chat Success!", Color.Green);\r
179                 WaitForSessionStart.Set();\r
180             }\r
181             else\r
182             {\r
183                 textManager.TextPrinter.PrintTextLine("Join Group Chat failed.", Color.Red);\r
184             }\r
185         }\r
186 \r
187         private void AddNetcomEvents()\r
188         {\r
189             netcom.ClientLoginStatus += new EventHandler<ClientLoginEventArgs>(netcom_ClientLoginStatus);\r
190             netcom.ClientDisconnected += new EventHandler<ClientDisconnectEventArgs>(netcom_ClientDisconnected);\r
191         }\r
192 \r
193         private void netcom_ClientLoginStatus(object sender, ClientLoginEventArgs e)\r
194         {\r
195             if (e.Status != LoginStatus.Success) return;\r
196 \r
197             RefreshControls();\r
198         }\r
199 \r
200         private void netcom_ClientDisconnected(object sender, ClientDisconnectEventArgs e)\r
201         {\r
202             RefreshControls();\r
203         }\r
204 \r
205         public void CleanUp()\r
206         {\r
207             textManager.CleanUp();\r
208             textManager = null;\r
209         }\r
210 \r
211         private void btnSend_Click(object sender, EventArgs e)\r
212         {\r
213             SendMsg();\r
214             this.ClearIMInput();\r
215         }\r
216 \r
217         private void btnShow_Click(object sender, EventArgs e)\r
218         {\r
219             if (chatSplit.Panel2Collapsed)\r
220             {\r
221                 chatSplit.Panel2Collapsed = false;\r
222                 btnShow.Text = "Hide";\r
223             }\r
224             else\r
225             {\r
226                 chatSplit.Panel2Collapsed = true;\r
227                 btnShow.Text = "Show";\r
228             }\r
229         }\r
230 \r
231         private void cbxInput_TextChanged(object sender, EventArgs e)\r
232         {\r
233             RefreshControls();\r
234         }\r
235 \r
236         private void RefreshControls()\r
237         {\r
238             if (!netcom.IsLoggedIn)\r
239             {\r
240                 cbxInput.Enabled = false;\r
241                 btnSend.Enabled = false;\r
242                 btnShow.Enabled = false;\r
243                 btnShow.Text = "Show";\r
244                 chatSplit.Panel2Collapsed = true;\r
245                 return;\r
246             }\r
247 \r
248             btnShow.Enabled = true;\r
249 \r
250             if (cbxInput.Text.Length > 0)\r
251             {\r
252                 btnSend.Enabled = true;\r
253             }\r
254             else\r
255             {\r
256                 btnSend.Enabled = false;\r
257             }\r
258         }\r
259 \r
260         private void cbxInput_KeyUp(object sender, KeyEventArgs e)\r
261         {\r
262             if (e.KeyCode != Keys.Enter) return;\r
263             e.SuppressKeyPress = true;\r
264 \r
265             SendMsg();\r
266         }\r
267 \r
268         private void SendMsg()\r
269         {\r
270             if (cbxInput.Text.Length == 0) return;\r
271 \r
272             string message = cbxInput.Text;\r
273             if (message.Length > 1023) message = message.Remove(1023);\r
274 \r
275             if (!client.Self.GroupChatSessions.ContainsKey(session))\r
276             {\r
277                 WaitForSessionStart.Reset();\r
278                 client.Self.RequestJoinGroupChat(session);\r
279             }\r
280             else\r
281             {\r
282                 WaitForSessionStart.Set();\r
283             }\r
284 \r
285             if (WaitForSessionStart.WaitOne(10000, false))\r
286             {\r
287                 client.Self.InstantMessageGroup(session, message);\r
288             }\r
289             else\r
290             {\r
291                 textManager.TextPrinter.PrintTextLine("Cannot send group IM.", Color.Red);\r
292             }\r
293             this.ClearIMInput();\r
294         }\r
295 \r
296         private void ClearIMInput()\r
297         {\r
298             cbxInput.Items.Add(cbxInput.Text);\r
299             cbxInput.Text = string.Empty;\r
300         }\r
301 \r
302         public void SelectIMInput()\r
303         {\r
304             cbxInput.Select();\r
305         }\r
306 \r
307         private void rtbIMText_LinkClicked(object sender, LinkClickedEventArgs e)\r
308         {\r
309             instance.MainForm.ProcessLink(e.LinkText);\r
310         }\r
311 \r
312         private void cbxInput_KeyDown(object sender, KeyEventArgs e)\r
313         {\r
314             if (e.KeyCode == Keys.Enter) e.SuppressKeyPress = true;\r
315         }\r
316 \r
317         public UUID SessionId\r
318         {\r
319             get { return session; }\r
320             set { session = value; }\r
321         }\r
322 \r
323         public IMTextManager TextManager\r
324         {\r
325             get { return textManager; }\r
326             set { textManager = value; }\r
327         }\r
328 \r
329         private void Participants_MouseDoubleClick(object sender, MouseEventArgs e)\r
330         {\r
331             ListViewItem item = Participants.GetItemAt(e.X, e.Y);\r
332             if (item != null)\r
333             {\r
334                 try\r
335                 {\r
336                     instance.MainForm.ShowAgentProfile(item.Text, new UUID(item.Name));\r
337                 }\r
338                 catch (Exception) { }\r
339             }\r
340         }\r
341 \r
342     }\r
343 }\r