OSDN Git Service

RAD-3: Added group chat participant list
[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.OnGroupChatJoin -= new AgentManager.GroupChatJoinedCallback(Self_OnGroupChatJoin);\r
75             client.Self.OnChatSessionMemberAdded -= new AgentManager.ChatSessionMemberAddedCallback(Self_OnChatSessionMemberAdded);\r
76             client.Self.OnChatSessionMemberLeft -= new AgentManager.ChatSessionMemberLeftCallback(Self_OnChatSessionMemberLeft);\r
77             client.Avatars.OnAvatarNames -= new AvatarManager.AvatarNamesCallback(Avatars_OnAvatarNames);\r
78             CleanUp();\r
79         }\r
80 \r
81         void Avatars_OnAvatarNames(Dictionary<UUID, string> names)\r
82         {\r
83             if (InvokeRequired)\r
84             {\r
85                 BeginInvoke(new MethodInvoker(() => Avatars_OnAvatarNames(names)));\r
86                 return;\r
87             }\r
88 \r
89             Participants.BeginUpdate();\r
90 \r
91             foreach (KeyValuePair<UUID, string> kvp in names)\r
92             {\r
93                 if (Participants.Items.ContainsKey(kvp.Key.ToString()))\r
94                     Participants.Items[kvp.Key.ToString()].Text = kvp.Value;\r
95             }\r
96 \r
97             Participants.Sort();\r
98             Participants.EndUpdate();\r
99         }\r
100 \r
101         void Self_OnChatSessionMemberLeft(UUID sessionID, UUID agent_key)\r
102         {\r
103             if (sessionID == session)\r
104                 UpdateParticipantList();\r
105         }\r
106 \r
107         void Self_OnChatSessionMemberAdded(UUID sessionID, UUID agent_key)\r
108         {\r
109             if (sessionID == session)\r
110                 UpdateParticipantList();\r
111         }\r
112 \r
113         void UpdateParticipantList()\r
114         {\r
115             if (InvokeRequired)\r
116             {\r
117                 BeginInvoke(new MethodInvoker(UpdateParticipantList));\r
118                 return;\r
119             }\r
120 \r
121             Participants.BeginUpdate();\r
122             Participants.Items.Clear();\r
123 \r
124             List<ChatSessionMember> participants;\r
125             List<UUID> nameLookup = new List<UUID>();\r
126 \r
127             if (client.Self.GroupChatSessions.TryGetValue(session, out participants))\r
128             {\r
129                 ChatSessionMember[] members = participants.ToArray();\r
130                 for (int i = 0; i < members.Length; i++)\r
131                 {\r
132                     ChatSessionMember participant = members[i];\r
133                     ListViewItem item = new ListViewItem();\r
134                     item.Name = participant.AvatarKey.ToString();\r
135                     if (instance.nameCache.ContainsKey(participant.AvatarKey))\r
136                     {\r
137                         item.Text = instance.nameCache[participant.AvatarKey];\r
138                     }\r
139                     else\r
140                     {\r
141                         item.Text = RadegastInstance.INCOMPLETE_NAME;\r
142                         nameLookup.Add(participant.AvatarKey);\r
143                     }\r
144                     if (participant.IsModerator)\r
145                         item.Font = new Font(item.Font, FontStyle.Bold);\r
146                     Participants.Items.Add(item);\r
147                 }\r
148 \r
149                 if (nameLookup.Count > 0)\r
150                     client.Avatars.RequestAvatarNames(nameLookup);\r
151             }\r
152 \r
153             Participants.Sort();\r
154             Participants.EndUpdate();\r
155         }\r
156 \r
157         void Self_OnGroupChatJoin(UUID groupChatSessionID, string sessionName, UUID tmpSessionID, bool success)\r
158         {\r
159             if (groupChatSessionID != session && tmpSessionID != session)\r
160             {\r
161                 return;\r
162             }\r
163 \r
164             if (InvokeRequired)\r
165             {\r
166                 Invoke(new MethodInvoker(\r
167                     delegate()\r
168                     {\r
169                         Self_OnGroupChatJoin(groupChatSessionID, sessionName, tmpSessionID, success);\r
170                     }\r
171                     )\r
172                 );\r
173                 return;\r
174             }\r
175             if (success)\r
176             {\r
177                 textManager.TextPrinter.PrintTextLine("Join Group Chat Success!", Color.Green);\r
178                 WaitForSessionStart.Set();\r
179             }\r
180             else\r
181             {\r
182                 textManager.TextPrinter.PrintTextLine("Join Group Chat failed.", Color.Red);\r
183             }\r
184         }\r
185 \r
186         private void AddNetcomEvents()\r
187         {\r
188             netcom.ClientLoginStatus += new EventHandler<ClientLoginEventArgs>(netcom_ClientLoginStatus);\r
189             netcom.ClientDisconnected += new EventHandler<ClientDisconnectEventArgs>(netcom_ClientDisconnected);\r
190         }\r
191 \r
192         private void netcom_ClientLoginStatus(object sender, ClientLoginEventArgs e)\r
193         {\r
194             if (e.Status != LoginStatus.Success) return;\r
195 \r
196             RefreshControls();\r
197         }\r
198 \r
199         private void netcom_ClientDisconnected(object sender, ClientDisconnectEventArgs e)\r
200         {\r
201             RefreshControls();\r
202         }\r
203 \r
204         public void CleanUp()\r
205         {\r
206             textManager.CleanUp();\r
207             textManager = null;\r
208         }\r
209 \r
210         private void btnSend_Click(object sender, EventArgs e)\r
211         {\r
212             SendMsg();\r
213             this.ClearIMInput();\r
214         }\r
215 \r
216         private void btnShow_Click(object sender, EventArgs e)\r
217         {\r
218             if (chatSplit.Panel2Collapsed)\r
219             {\r
220                 chatSplit.Panel2Collapsed = false;\r
221                 btnShow.Text = "Hide";\r
222             }\r
223             else\r
224             {\r
225                 chatSplit.Panel2Collapsed = true;\r
226                 btnShow.Text = "Show";\r
227             }\r
228         }\r
229 \r
230         private void cbxInput_TextChanged(object sender, EventArgs e)\r
231         {\r
232             RefreshControls();\r
233         }\r
234 \r
235         private void RefreshControls()\r
236         {\r
237             if (!netcom.IsLoggedIn)\r
238             {\r
239                 cbxInput.Enabled = false;\r
240                 btnSend.Enabled = false;\r
241                 btnShow.Enabled = false;\r
242                 btnShow.Text = "Show";\r
243                 chatSplit.Panel2Collapsed = true;\r
244                 return;\r
245             }\r
246 \r
247             btnShow.Enabled = true;\r
248 \r
249             if (cbxInput.Text.Length > 0)\r
250             {\r
251                 btnSend.Enabled = true;\r
252             }\r
253             else\r
254             {\r
255                 btnSend.Enabled = false;\r
256             }\r
257         }\r
258 \r
259         private void cbxInput_KeyUp(object sender, KeyEventArgs e)\r
260         {\r
261             if (e.KeyCode != Keys.Enter) return;\r
262             e.SuppressKeyPress = true;\r
263 \r
264             SendMsg();\r
265         }\r
266 \r
267         private void SendMsg()\r
268         {\r
269             if (cbxInput.Text.Length == 0) return;\r
270 \r
271             string message = cbxInput.Text;\r
272             if (message.Length > 1023) message = message.Remove(1023);\r
273 \r
274             if (!client.Self.GroupChatSessions.ContainsKey(session))\r
275             {\r
276                 WaitForSessionStart.Reset();\r
277                 client.Self.RequestJoinGroupChat(session);\r
278             }\r
279             else\r
280             {\r
281                 WaitForSessionStart.Set();\r
282             }\r
283 \r
284             if (WaitForSessionStart.WaitOne(10000, false))\r
285             {\r
286                 client.Self.InstantMessageGroup(session, message);\r
287             }\r
288             else\r
289             {\r
290                 textManager.TextPrinter.PrintTextLine("Cannot send group IM.", Color.Red);\r
291             }\r
292             this.ClearIMInput();\r
293         }\r
294 \r
295         private void ClearIMInput()\r
296         {\r
297             cbxInput.Items.Add(cbxInput.Text);\r
298             cbxInput.Text = string.Empty;\r
299         }\r
300 \r
301         public void SelectIMInput()\r
302         {\r
303             cbxInput.Select();\r
304         }\r
305 \r
306         private void rtbIMText_LinkClicked(object sender, LinkClickedEventArgs e)\r
307         {\r
308             instance.MainForm.ProcessLink(e.LinkText);\r
309         }\r
310 \r
311         private void cbxInput_KeyDown(object sender, KeyEventArgs e)\r
312         {\r
313             if (e.KeyCode == Keys.Enter) e.SuppressKeyPress = true;\r
314         }\r
315 \r
316         public UUID SessionId\r
317         {\r
318             get { return session; }\r
319             set { session = value; }\r
320         }\r
321 \r
322         public IMTextManager TextManager\r
323         {\r
324             get { return textManager; }\r
325             set { textManager = value; }\r
326         }\r
327 \r
328         private void Participants_MouseDoubleClick(object sender, MouseEventArgs e)\r
329         {\r
330             ListViewItem item = Participants.GetItemAt(e.X, e.Y);\r
331             if (item != null)\r
332             {\r
333                 try\r
334                 {\r
335                     new frmProfile(instance, item.Text, new UUID(item.Name)).Show();\r
336                 }\r
337                 catch (Exception) { }\r
338             }\r
339         }\r
340 \r
341     }\r
342 }\r