OSDN Git Service

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