OSDN Git Service

RAD-5 Added ctrl-right arrow and ctrl-left arrow for navigating to next and prevoius...
[radegast/radegast.git] / Radegast / GUI / Consoles / TabsConsole.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.Collections.Generic;\r
33 using System.ComponentModel;\r
34 using System.Drawing;\r
35 using System.Windows.Forms;\r
36 using Radegast.Netcom;\r
37 using OpenMetaverse;\r
38 \r
39 namespace Radegast\r
40 {\r
41     public partial class TabsConsole : 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 ChatTextManager mainChatManger;\r
47 \r
48         public Dictionary<string, SleekTab> tabs = new Dictionary<string, SleekTab>();\r
49         private ChatConsole chatConsole;\r
50 \r
51         private SleekTab selectedTab;\r
52         public SleekTab SelectedTab\r
53         {\r
54             get\r
55             {\r
56                 return selectedTab;\r
57             }\r
58         }\r
59 \r
60         private Form owner;\r
61 \r
62         public TabsConsole(RadegastInstance instance)\r
63         {\r
64             InitializeComponent();\r
65             Disposed += new EventHandler(TabsConsole_Disposed);\r
66 \r
67             this.instance = instance;\r
68 \r
69             AddNetcomEvents();\r
70 \r
71             InitializeMainTab();\r
72             InitializeChatTab();\r
73 \r
74             // Callbacks\r
75             client.Self.OnScriptQuestion += new AgentManager.ScriptQuestionCallback(Self_OnScriptQuestion);\r
76             client.Self.OnScriptDialog += new AgentManager.ScriptDialogCallback(Self_OnScriptDialog);\r
77             client.Inventory.OnObjectOffered += new InventoryManager.ObjectOfferedCallback(Inventory_OnObjectOffered);\r
78         }\r
79 \r
80         void TabsConsole_Disposed(object sender, EventArgs e)\r
81         {\r
82             RemoveNetcomEvents();\r
83             client.Self.OnScriptQuestion -= new AgentManager.ScriptQuestionCallback(Self_OnScriptQuestion);\r
84             client.Self.OnScriptDialog -= new AgentManager.ScriptDialogCallback(Self_OnScriptDialog);\r
85             client.Inventory.OnObjectOffered -= new InventoryManager.ObjectOfferedCallback(Inventory_OnObjectOffered);\r
86         }\r
87 \r
88         private void AddNetcomEvents()\r
89         {\r
90             netcom.ClientLoginStatus += new EventHandler<ClientLoginEventArgs>(netcom_ClientLoginStatus);\r
91             netcom.ClientLoggedOut += new EventHandler(netcom_ClientLoggedOut);\r
92             netcom.ClientDisconnected += new EventHandler<ClientDisconnectEventArgs>(netcom_ClientDisconnected);\r
93             netcom.ChatReceived += new EventHandler<ChatEventArgs>(netcom_ChatReceived);\r
94             netcom.ChatSent += new EventHandler<ChatSentEventArgs>(netcom_ChatSent);\r
95             netcom.AlertMessageReceived += new EventHandler<AlertMessageEventArgs>(netcom_AlertMessageReceived);\r
96             netcom.InstantMessageReceived += new EventHandler<InstantMessageEventArgs>(netcom_InstantMessageReceived);\r
97         }\r
98 \r
99         private void RemoveNetcomEvents()\r
100         {\r
101             netcom.ClientLoginStatus -= new EventHandler<ClientLoginEventArgs>(netcom_ClientLoginStatus);\r
102             netcom.ClientLoggedOut -= new EventHandler(netcom_ClientLoggedOut);\r
103             netcom.ClientDisconnected -= new EventHandler<ClientDisconnectEventArgs>(netcom_ClientDisconnected);\r
104             netcom.ChatReceived -= new EventHandler<ChatEventArgs>(netcom_ChatReceived);\r
105             netcom.ChatSent -= new EventHandler<ChatSentEventArgs>(netcom_ChatSent);\r
106             netcom.AlertMessageReceived -= new EventHandler<AlertMessageEventArgs>(netcom_AlertMessageReceived);\r
107             netcom.InstantMessageReceived -= new EventHandler<InstantMessageEventArgs>(netcom_InstantMessageReceived);\r
108         }\r
109 \r
110         bool Inventory_OnObjectOffered(InstantMessage offerDetails, AssetType type, UUID objectID, bool fromTask)\r
111         {\r
112             DisplayNotificationInChat(offerDetails.FromAgentName + " gave you " + offerDetails.Message);\r
113             return true;\r
114         }\r
115 \r
116         void Self_OnScriptDialog(string message, string objectName, UUID imageID, UUID objectID, string firstName, string lastName, int chatChannel, List<string> buttons)\r
117         {\r
118             instance.MainForm.AddNotification(new ntfScriptDialog(instance, message, objectName, imageID, objectID, firstName, lastName, chatChannel, buttons));\r
119         }\r
120 \r
121         void Self_OnScriptQuestion(Simulator simulator, UUID taskID, UUID itemID, string objectName, string objectOwner, ScriptPermission questions)\r
122         {\r
123             instance.MainForm.AddNotification(new ntfPermissions(instance, simulator, taskID, itemID, objectName, objectOwner, questions));\r
124         }\r
125 \r
126         private void netcom_ClientLoginStatus(object sender, ClientLoginEventArgs e)\r
127         {\r
128             if (e.Status != LoginStatus.Success) return;\r
129 \r
130             InitializeFriendsTab();\r
131             InitializeInventoryTab();\r
132             InitializeSearchTab();\r
133 \r
134             if (selectedTab.Name == "login")\r
135                 tabs["chat"].Select();\r
136 \r
137             tabs["login"].AllowClose = true;\r
138             tabs["login"].Close();\r
139 \r
140             client.Self.RetrieveInstantMessages();\r
141         }\r
142 \r
143         private void netcom_ClientLoggedOut(object sender, EventArgs e)\r
144         {\r
145             DisposeSearchTab();\r
146             DisposeInventoryTab();\r
147             DisposeFriendsTab();\r
148 \r
149             tabs["chat"].Select();\r
150             DisplayNotificationInChat("Logged out.");\r
151             \r
152         }\r
153 \r
154         private void netcom_ClientDisconnected(object sender, ClientDisconnectEventArgs e)\r
155         {\r
156             if (e.Type == NetworkManager.DisconnectType.ClientInitiated) return;\r
157 \r
158             DisposeSearchTab();\r
159             DisposeInventoryTab();\r
160             DisposeFriendsTab();\r
161 \r
162             tabs["chat"].Select();\r
163             DisplayNotificationInChat("Disconnected.");\r
164         }\r
165 \r
166         private void netcom_AlertMessageReceived(object sender, AlertMessageEventArgs e)\r
167         {\r
168             tabs["chat"].Highlight();\r
169         }\r
170 \r
171         private void netcom_ChatSent(object sender, ChatSentEventArgs e)\r
172         {\r
173             tabs["chat"].Highlight();\r
174         }\r
175 \r
176         private void netcom_ChatReceived(object sender, ChatEventArgs e)\r
177         {\r
178             if (string.IsNullOrEmpty(e.Message)) return;\r
179 \r
180             tabs["chat"].Highlight();\r
181         }\r
182 \r
183         private void netcom_InstantMessageReceived(object sender, InstantMessageEventArgs e)\r
184         {\r
185             switch (e.IM.Dialog)\r
186             {\r
187                 case InstantMessageDialog.SessionSend:\r
188                     if (instance.Groups.ContainsKey(e.IM.IMSessionID))\r
189                     {\r
190                         HandleGroupIM(e);\r
191                     }\r
192                     else\r
193                     {\r
194                         HandleConferenceIM(e);\r
195                     }\r
196                     break;\r
197 \r
198                 case InstantMessageDialog.MessageFromAgent:\r
199                     if (e.IM.FromAgentName == "Second Life")\r
200                     {\r
201                         HandleIMFromObject(e);\r
202                     }\r
203                     else if (e.IM.GroupIM || instance.Groups.ContainsKey(e.IM.IMSessionID))\r
204                     {\r
205                         HandleGroupIM(e);\r
206                     }\r
207                     else if (e.IM.BinaryBucket.Length > 1)\r
208                     { // conference\r
209                         HandleConferenceIM(e);\r
210                     }\r
211                     else\r
212                     {\r
213                         HandleIM(e);\r
214                     }\r
215                     break;\r
216 \r
217                 case InstantMessageDialog.MessageFromObject:\r
218                     HandleIMFromObject(e);\r
219                     break;\r
220 \r
221                 case InstantMessageDialog.StartTyping:\r
222                     if (TabExists(e.IM.FromAgentName))\r
223                     {\r
224                         SleekTab tab = tabs[e.IM.FromAgentName.ToLower()];\r
225                         if (!tab.Highlighted) tab.PartialHighlight();\r
226                     }\r
227 \r
228                     break;\r
229 \r
230                 case InstantMessageDialog.StopTyping:\r
231                     if (TabExists(e.IM.FromAgentName))\r
232                     {\r
233                         SleekTab tab = tabs[e.IM.FromAgentName.ToLower()];\r
234                         if (!tab.Highlighted) tab.Unhighlight();\r
235                     }\r
236 \r
237                     break;\r
238 \r
239                 case InstantMessageDialog.MessageBox:\r
240                     instance.MainForm.AddNotification(new ntfGeneric(instance, e.IM.Message));\r
241                     break;\r
242 \r
243                 case InstantMessageDialog.RequestTeleport:\r
244                     instance.MainForm.AddNotification(new ntfTeleport(instance, e.IM));\r
245                     break;\r
246 \r
247                 case InstantMessageDialog.GroupInvitation:\r
248                     instance.MainForm.AddNotification(new ntfGroupInvitation(instance, e.IM));\r
249                     break;\r
250 \r
251                 case InstantMessageDialog.FriendshipOffered:\r
252                     instance.MainForm.AddNotification(new ntfFriendshipOffer(instance, e.IM));\r
253                     break;\r
254 \r
255                 case InstantMessageDialog.InventoryAccepted:\r
256                     DisplayNotificationInChat(e.IM.FromAgentName + " accepted your inventory offer.");\r
257                     break;\r
258 \r
259                 case InstantMessageDialog.GroupNotice:\r
260                     instance.MainForm.AddNotification(new ntfGroupNotice(instance, e.IM));\r
261                     break;\r
262             }\r
263         }\r
264 \r
265         public void DisplayNotificationInChat(string msg)\r
266         {\r
267             if (InvokeRequired)\r
268             {\r
269                 BeginInvoke(new MethodInvoker(delegate()\r
270                     {\r
271                         DisplayNotificationInChat(msg);\r
272                     }));\r
273                 return;\r
274             }\r
275 \r
276             ChatBufferItem line = new ChatBufferItem(\r
277                 DateTime.Now,\r
278                 msg,\r
279                 ChatBufferTextStyle.ObjectChat\r
280             );\r
281             try\r
282             {\r
283                 mainChatManger.ProcessBufferItem(line, true);\r
284                 tabs["chat"].Highlight();\r
285             }\r
286             catch (Exception) { }\r
287         }\r
288 \r
289         private void HandleIMFromObject(InstantMessageEventArgs e)\r
290         {\r
291             DisplayNotificationInChat(e.IM.FromAgentName + ": " + e.IM.Message);\r
292         }\r
293 \r
294         private void HandleIM(InstantMessageEventArgs e)\r
295         {\r
296             if (TabExists(e.IM.IMSessionID.ToString()))\r
297             {\r
298                 SleekTab tab = tabs[e.IM.IMSessionID.ToString()];\r
299                 if (!tab.Selected) tab.Highlight();\r
300                 return;\r
301             }\r
302 \r
303             IMTabWindow imTab = AddIMTab(e);\r
304             tabs[e.IM.IMSessionID.ToString()].Highlight();\r
305         }\r
306 \r
307         private void HandleConferenceIM(InstantMessageEventArgs e)\r
308         {\r
309             if (TabExists(e.IM.IMSessionID.ToString()))\r
310             {\r
311                 SleekTab tab = tabs[e.IM.IMSessionID.ToString()];\r
312                 if (!tab.Selected) tab.Highlight();\r
313                 return;\r
314             }\r
315 \r
316             ConferenceIMTabWindow imTab = AddConferenceIMTab(e);\r
317             tabs[e.IM.IMSessionID.ToString()].Highlight();\r
318         }\r
319 \r
320         private void HandleGroupIM(InstantMessageEventArgs e)\r
321         {\r
322             if (TabExists(e.IM.IMSessionID.ToString())) {\r
323                 SleekTab tab = tabs[e.IM.IMSessionID.ToString()];\r
324                 if (!tab.Selected) tab.Highlight();\r
325                 return;\r
326             }\r
327 \r
328             GroupIMTabWindow imTab = AddGroupIMTab(e);\r
329             tabs[e.IM.IMSessionID.ToString()].Highlight();\r
330         }\r
331 \r
332         private void InitializeMainTab()\r
333         {\r
334             MainConsole mainConsole = new MainConsole(instance);\r
335             mainConsole.Dock = DockStyle.Fill;\r
336             mainConsole.Visible = false;\r
337 \r
338             toolStripContainer1.ContentPanel.Controls.Add(mainConsole);\r
339 \r
340             SleekTab tab = AddTab("login", "Login", mainConsole);\r
341             tab.AllowClose = false;\r
342             tab.AllowDetach = false;\r
343             tab.AllowMerge = false;\r
344 \r
345             mainConsole.RegisterTab(tab);\r
346         }\r
347 \r
348         private void InitializeChatTab()\r
349         {\r
350             chatConsole = new ChatConsole(instance);\r
351             mainChatManger = chatConsole.ChatManager;\r
352             chatConsole.Dock = DockStyle.Fill;\r
353             chatConsole.Visible = false;\r
354 \r
355             toolStripContainer1.ContentPanel.Controls.Add(chatConsole);\r
356 \r
357             SleekTab tab = AddTab("chat", "Chat", chatConsole);\r
358             tab.AllowClose = false;\r
359             tab.AllowDetach = false;\r
360         }\r
361 \r
362         private void InitializeFriendsTab()\r
363         {\r
364             FriendsConsole friendsConsole = new FriendsConsole(instance);\r
365             friendsConsole.Dock = DockStyle.Fill;\r
366             friendsConsole.Visible = false;\r
367 \r
368             toolStripContainer1.ContentPanel.Controls.Add(friendsConsole);\r
369 \r
370             SleekTab tab = AddTab("friends", "Friends", friendsConsole);\r
371             tab.AllowClose = false;\r
372             tab.AllowDetach = false;\r
373         }\r
374 \r
375         private void InitializeSearchTab()\r
376         {\r
377             SearchConsole searchConsole = new SearchConsole(instance);\r
378             searchConsole.Dock = DockStyle.Fill;\r
379             searchConsole.Visible = false;\r
380 \r
381             toolStripContainer1.ContentPanel.Controls.Add(searchConsole);\r
382 \r
383             SleekTab tab = AddTab("search", "Search", searchConsole);\r
384             tab.AllowClose = false;\r
385             tab.AllowDetach = false;\r
386         }\r
387 \r
388         private void InitializeInventoryTab()\r
389         {\r
390             InventoryConsole invConsole = new InventoryConsole(instance);\r
391             invConsole.Dock = DockStyle.Fill;\r
392             invConsole.Visible = true;\r
393 \r
394             toolStripContainer1.ContentPanel.Controls.Add(invConsole);\r
395 \r
396             SleekTab tab = AddTab("inventory", "Inventory", invConsole);\r
397             tab.AllowClose = false;\r
398             tab.AllowDetach = true;\r
399         }\r
400 \r
401         private void DisposeFriendsTab()\r
402         {\r
403             ForceCloseTab("friends");\r
404         }\r
405 \r
406         private void DisposeSearchTab()\r
407         {\r
408             ForceCloseTab("search");\r
409         }\r
410 \r
411         private void DisposeInventoryTab()\r
412         {\r
413             ForceCloseTab("inventory");\r
414         }\r
415 \r
416         private void ForceCloseTab(string name)\r
417         {\r
418             if (!TabExists(name)) return;\r
419 \r
420             SleekTab tab = tabs[name];\r
421             if (tab.Merged) SplitTab(tab);\r
422 \r
423             tab.AllowClose = true;\r
424             tab.Close();\r
425             tab = null;\r
426         }\r
427 \r
428         public void AddTab(SleekTab tab)\r
429         {\r
430             ToolStripButton button = (ToolStripButton)tstTabs.Items.Add(tab.Label);\r
431             button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;\r
432             button.Image = null;\r
433             button.AutoToolTip = false;\r
434             button.Tag = tab.Name;\r
435             button.Click += new EventHandler(TabButtonClick);\r
436             tab.Button = button;\r
437             tabs.Add(tab.Name, tab);\r
438         }\r
439 \r
440         public SleekTab AddTab(string name, string label, Control control)\r
441         {\r
442             ToolStripButton button = (ToolStripButton)tstTabs.Items.Add(label);\r
443             button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;\r
444             button.Image = null;\r
445             button.AutoToolTip = false;\r
446             button.Tag = name.ToLower();\r
447             button.Click += new EventHandler(TabButtonClick);\r
448 \r
449             SleekTab tab = new SleekTab(instance, button, control, name.ToLower(), label);\r
450             tab.TabAttached += new EventHandler(tab_TabAttached);\r
451             tab.TabDetached += new EventHandler(tab_TabDetached);\r
452             tab.TabSelected += new EventHandler(tab_TabSelected);\r
453             tab.TabClosed += new EventHandler(tab_TabClosed);\r
454             tabs.Add(name.ToLower(), tab);\r
455 \r
456             return tab;\r
457         }\r
458 \r
459         private void tab_TabAttached(object sender, EventArgs e)\r
460         {\r
461             SleekTab tab = (SleekTab)sender;\r
462             tab.Select();\r
463         }\r
464 \r
465         private void tab_TabDetached(object sender, EventArgs e)\r
466         {\r
467             SleekTab tab = (SleekTab)sender;\r
468             frmDetachedTab form = (frmDetachedTab)tab.Owner;\r
469 \r
470             form.ReattachStrip = tstTabs;\r
471             form.ReattachContainer = toolStripContainer1.ContentPanel;\r
472         }\r
473 \r
474         private void tab_TabSelected(object sender, EventArgs e)\r
475         {\r
476             SleekTab tab = (SleekTab)sender;\r
477 \r
478             if (selectedTab != null &&\r
479                 selectedTab != tab)\r
480             { selectedTab.Deselect(); }\r
481             \r
482             selectedTab = tab;\r
483 \r
484             tbtnCloseTab.Enabled = tab.AllowClose;\r
485             owner.AcceptButton = tab.DefaultControlButton;\r
486         }\r
487 \r
488         private void tab_TabClosed(object sender, EventArgs e)\r
489         {\r
490             SleekTab tab = (SleekTab)sender;\r
491             \r
492             tabs.Remove(tab.Name);\r
493             tab = null;\r
494         }\r
495 \r
496         private void TabButtonClick(object sender, EventArgs e)\r
497         {\r
498             ToolStripButton button = (ToolStripButton)sender;\r
499 \r
500             SleekTab tab = tabs[button.Tag.ToString()];\r
501             tab.Select();\r
502         }\r
503 \r
504         public void RemoveTabEntry(SleekTab tab)\r
505         {\r
506             if (tstTabs.Items.Contains(tab.Button))\r
507             {\r
508                 tstTabs.Items.Remove(tab.Button);\r
509             }\r
510 \r
511             tab.Button.Dispose();\r
512             tabs.Remove(tab.Name);\r
513         }\r
514 \r
515         public void RemoveTab(string name)\r
516         {\r
517             if (tabs.ContainsKey(name))\r
518             {\r
519                 tabs.Remove(name);\r
520             }\r
521         }\r
522 \r
523         //Used for outside classes that have a reference to TabsConsole\r
524         public void SelectTab(string name)\r
525         {\r
526             tabs[name.ToLower()].Select();\r
527         }\r
528 \r
529         public bool TabExists(string name)\r
530         {\r
531             return tabs.ContainsKey(name.ToLower());\r
532         }\r
533 \r
534         public SleekTab GetTab(string name)\r
535         {\r
536             return tabs[name.ToLower()];\r
537         }\r
538 \r
539         public List<SleekTab> GetOtherTabs()\r
540         {\r
541             List<SleekTab> otherTabs = new List<SleekTab>();\r
542 \r
543             foreach (ToolStripItem item in tstTabs.Items)\r
544             {\r
545                 if (item.Tag == null) continue;\r
546                 if ((ToolStripItem)item == selectedTab.Button) continue;\r
547 \r
548                 SleekTab tab = tabs[item.Tag.ToString()];\r
549                 if (!tab.AllowMerge) continue;\r
550                 if (tab.Merged) continue;\r
551                 \r
552                 otherTabs.Add(tab);\r
553             }\r
554 \r
555             return otherTabs;\r
556         }\r
557 \r
558         /// <summary>\r
559         /// Activates the next tab\r
560         /// </summary>\r
561         public void SelectNextTab()\r
562         {\r
563             List<ToolStripItem> buttons = new List<ToolStripItem>();\r
564 \r
565             foreach (ToolStripItem item in tstTabs.Items)\r
566             {\r
567                 if (item.Tag == null) continue;\r
568 \r
569                 buttons.Add(item);\r
570             }\r
571 \r
572             int current = 0;\r
573 \r
574             for (int i = 0; i < buttons.Count; i++)\r
575             {\r
576                 if (buttons[i] == selectedTab.Button)\r
577                 {\r
578                     current = i;\r
579                     break;\r
580                 }\r
581             }\r
582 \r
583             current++;\r
584 \r
585             if (current == buttons.Count)\r
586                 current = 0;\r
587 \r
588             SelectTab(tabs[buttons[current].Tag.ToString()].Name);\r
589         }\r
590 \r
591         /// <summary>\r
592         /// Activates the previous tab\r
593         /// </summary>\r
594         public void SelectPreviousTab()\r
595         {\r
596             List<ToolStripItem> buttons = new List<ToolStripItem>();\r
597 \r
598             foreach (ToolStripItem item in tstTabs.Items)\r
599             {\r
600                 if (item.Tag == null) continue;\r
601 \r
602                 buttons.Add(item);\r
603             }\r
604 \r
605             int current = 0;\r
606 \r
607             for (int i = 0; i < buttons.Count; i++)\r
608             {\r
609                 if (buttons[i] == selectedTab.Button)\r
610                 {\r
611                     current = i;\r
612                     break;\r
613                 }\r
614             }\r
615 \r
616             current--;\r
617 \r
618             if (current == -1)\r
619                 current = buttons.Count - 1;\r
620 \r
621             SelectTab(tabs[buttons[current].Tag.ToString()].Name);\r
622         }\r
623 \r
624 \r
625         public IMTabWindow AddIMTab(UUID target, UUID session, string targetName)\r
626         {\r
627             IMTabWindow imTab = new IMTabWindow(instance, target, session, targetName);\r
628             imTab.Dock = DockStyle.Fill;\r
629 \r
630             toolStripContainer1.ContentPanel.Controls.Add(imTab);\r
631             SleekTab tab = AddTab(session.ToString(), "IM: " + targetName, imTab);\r
632             SelectTab(session.ToString());\r
633             imTab.SelectIMInput();\r
634 \r
635             return imTab;\r
636         }\r
637 \r
638         public ConferenceIMTabWindow AddConferenceIMTab(UUID session, string name)\r
639         {\r
640             ConferenceIMTabWindow imTab = new ConferenceIMTabWindow(instance, session, name);\r
641             imTab.Dock = DockStyle.Fill;\r
642 \r
643             toolStripContainer1.ContentPanel.Controls.Add(imTab);\r
644             SleekTab tab = AddTab(session.ToString(), name, imTab);\r
645             imTab.SelectIMInput();\r
646 \r
647             return imTab;\r
648         }\r
649 \r
650 \r
651         public ConferenceIMTabWindow AddConferenceIMTab(InstantMessageEventArgs e)\r
652         {\r
653             ConferenceIMTabWindow imTab = AddConferenceIMTab(e.IM.IMSessionID, Utils.BytesToString(e.IM.BinaryBucket));\r
654             imTab.TextManager.ProcessIM(e);\r
655             return imTab;\r
656         }\r
657 \r
658         public GroupIMTabWindow AddGroupIMTab(UUID session, string name)\r
659         {\r
660             GroupIMTabWindow imTab = new GroupIMTabWindow(instance, session, name);\r
661             imTab.Dock = DockStyle.Fill;\r
662 \r
663             toolStripContainer1.ContentPanel.Controls.Add(imTab);\r
664             SleekTab tab = AddTab(session.ToString(), name, imTab);\r
665             imTab.SelectIMInput();\r
666 \r
667             return imTab;\r
668         }\r
669 \r
670         public GroupIMTabWindow AddGroupIMTab(InstantMessageEventArgs e)\r
671         {\r
672             GroupIMTabWindow imTab = AddGroupIMTab(e.IM.IMSessionID, Utils.BytesToString(e.IM.BinaryBucket));\r
673             imTab.TextManager.ProcessIM(e);\r
674             return imTab;\r
675         }\r
676         \r
677         public IMTabWindow AddIMTab(InstantMessageEventArgs e)\r
678         {\r
679             IMTabWindow imTab = AddIMTab(e.IM.FromAgentID, e.IM.IMSessionID, e.IM.FromAgentName);\r
680             imTab.TextManager.ProcessIM(e);\r
681             return imTab;\r
682         }\r
683 \r
684         public OutfitTextures AddOTTab(Avatar avatar)\r
685         {\r
686             OutfitTextures otTab = new OutfitTextures(instance, avatar);\r
687             otTab.Dock = DockStyle.Fill;\r
688             toolStripContainer1.ContentPanel.Controls.Add(otTab);\r
689             SleekTab tab = AddTab("OT: " + avatar.Name, "OT: " + avatar.Name, otTab);\r
690             otTab.GetTextures();\r
691             return otTab;\r
692         }\r
693 \r
694         public MasterTab AddMSTab(Avatar avatar)\r
695         {\r
696             MasterTab msTab = new MasterTab(instance, avatar);\r
697             msTab.Dock = DockStyle.Fill;\r
698             toolStripContainer1.ContentPanel.Controls.Add(msTab);\r
699             SleekTab tab = AddTab("MS: " + avatar.Name, "MS: " + avatar.Name, msTab);\r
700             // msTab.GetTextures();\r
701             return msTab;\r
702         }\r
703 \r
704         public AttachmentTab AddATTab(Avatar avatar)\r
705         {\r
706             AttachmentTab atTab = new AttachmentTab(instance, avatar);\r
707             atTab.Dock = DockStyle.Fill;\r
708             toolStripContainer1.ContentPanel.Controls.Add(atTab);\r
709             SleekTab tab = AddTab("AT: " + avatar.Name, "AT: " + avatar.Name, atTab);\r
710             return atTab;\r
711         }\r
712 \r
713         public AnimTab AddAnimTab(Avatar avatar)\r
714         {\r
715             AnimTab animTab = new AnimTab(instance, avatar);\r
716             animTab.Dock = DockStyle.Fill;\r
717             toolStripContainer1.ContentPanel.Controls.Add(animTab);\r
718             SleekTab tab = AddTab("Anim: " + avatar.Name, "Anim: " + avatar.Name, animTab);\r
719             return animTab;\r
720         }\r
721 \r
722         private void tbtnTabOptions_Click(object sender, EventArgs e)\r
723         {\r
724             tmnuMergeWith.Enabled = selectedTab.AllowMerge;\r
725             tmnuDetachTab.Enabled = selectedTab.AllowDetach;\r
726 \r
727             tmnuMergeWith.DropDown.Items.Clear();\r
728 \r
729             if (!selectedTab.AllowMerge) return;\r
730             if (!selectedTab.Merged)\r
731             {\r
732                 tmnuMergeWith.Text = "Merge With";\r
733 \r
734                 List<SleekTab> otherTabs = GetOtherTabs();\r
735 \r
736                 tmnuMergeWith.Enabled = (otherTabs.Count > 0);\r
737                 if (!tmnuMergeWith.Enabled) return;\r
738 \r
739                 foreach (SleekTab tab in otherTabs)\r
740                 {\r
741                     ToolStripItem item = tmnuMergeWith.DropDown.Items.Add(tab.Label);\r
742                     item.Tag = tab.Name;\r
743                     item.Click += new EventHandler(MergeItemClick);\r
744                 }\r
745             }\r
746             else\r
747             {\r
748                 tmnuMergeWith.Text = "Split";\r
749                 tmnuMergeWith.Click += new EventHandler(SplitClick);\r
750             }\r
751         }\r
752 \r
753         private void MergeItemClick(object sender, EventArgs e)\r
754         {\r
755             ToolStripItem item = (ToolStripItem)sender;\r
756             SleekTab tab = tabs[item.Tag.ToString()];\r
757 \r
758             selectedTab.MergeWith(tab);\r
759 \r
760             SplitContainer container = (SplitContainer)selectedTab.Control;\r
761             toolStripContainer1.ContentPanel.Controls.Add(container);\r
762 \r
763             selectedTab.Select();\r
764             RemoveTabEntry(tab);\r
765 \r
766             tabs.Add(tab.Name, selectedTab);\r
767         }\r
768 \r
769         private void SplitClick(object sender, EventArgs e)\r
770         {\r
771             SplitTab(selectedTab);\r
772             selectedTab.Select();\r
773         }\r
774 \r
775         public void SplitTab(SleekTab tab)\r
776         {\r
777             SleekTab otherTab = tab.Split();\r
778             if (otherTab == null) return;\r
779 \r
780             toolStripContainer1.ContentPanel.Controls.Add(tab.Control);\r
781             toolStripContainer1.ContentPanel.Controls.Add(otherTab.Control);\r
782 \r
783             tabs.Remove(otherTab.Name);\r
784             AddTab(otherTab);\r
785         }\r
786 \r
787         private void tmnuDetachTab_Click(object sender, EventArgs e)\r
788         {\r
789             if (!selectedTab.AllowDetach) return;\r
790 \r
791             tstTabs.Items.Remove(selectedTab.Button);\r
792             selectedTab.Detach(instance);\r
793             selectedTab.Owner.Show();\r
794 \r
795             tabs["chat"].Select();\r
796         }\r
797 \r
798         private void tbtnCloseTab_Click(object sender, EventArgs e)\r
799         {\r
800             SleekTab tab = selectedTab;\r
801 \r
802             tabs["chat"].Select();\r
803             tab.Close();\r
804             \r
805             tab = null;\r
806         }\r
807 \r
808         private void TabsConsole_Load(object sender, EventArgs e)\r
809         {\r
810             owner = this.FindForm();\r
811         }\r
812 \r
813         private void ctxTabs_Opening(object sender, CancelEventArgs e)\r
814         {\r
815             Point pt = this.PointToClient(Cursor.Position);\r
816             ToolStripItem stripItem = tstTabs.GetItemAt(pt);\r
817 \r
818             if (stripItem == null)\r
819             {\r
820                 e.Cancel = true;\r
821             }\r
822             else\r
823             {\r
824                 tabs[stripItem.Tag.ToString()].Select();\r
825 \r
826                 ctxBtnClose.Enabled = selectedTab.AllowClose;\r
827                 ctxBtnDetach.Enabled = selectedTab.AllowDetach;\r
828                 ctxBtnMerge.Enabled = selectedTab.AllowMerge;\r
829                 ctxBtnMerge.DropDown.Items.Clear();\r
830 \r
831                 if (!ctxBtnClose.Enabled && !ctxBtnDetach.Enabled && !ctxBtnMerge.Enabled)\r
832                 {\r
833                     e.Cancel = true;\r
834                     return;\r
835                 }\r
836 \r
837                 if (!selectedTab.AllowMerge) return;\r
838                 if (!selectedTab.Merged)\r
839                 {\r
840                     ctxBtnMerge.Text = "Merge With";\r
841 \r
842                     List<SleekTab> otherTabs = GetOtherTabs();\r
843 \r
844                     ctxBtnMerge.Enabled = (otherTabs.Count > 0);\r
845                     if (!ctxBtnMerge.Enabled) return;\r
846 \r
847                     foreach (SleekTab tab in otherTabs)\r
848                     {\r
849                         ToolStripItem item = ctxBtnMerge.DropDown.Items.Add(tab.Label);\r
850                         item.Tag = tab.Name;\r
851                         item.Click += new EventHandler(MergeItemClick);\r
852                     }\r
853                 }\r
854                 else\r
855                 {\r
856                     ctxBtnMerge.Text = "Split";\r
857                     ctxBtnMerge.Click += new EventHandler(SplitClick);\r
858                 }\r
859 \r
860             }\r
861         }\r
862     }\r
863 }\r