OSDN Git Service

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