2 // Radegast Metaverse Client
\r
3 // Copyright (c) 2009, Radegast Development Team
\r
4 // All rights reserved.
\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
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
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
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
41 public partial class TabsConsole : UserControl
\r
44 /// Delegate invoked on tab operations
\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
51 /// Fired when a tab is selected
\r
53 public event TabCallback OnTabSelected;
\r
57 /// Delegate invoked when chat notification is printed
\r
59 /// <param name="sender">Event sender</param>
\r
60 /// <param name="e">Event arguments</param>
\r
61 public delegate void ChatNotificationCallback(object sender, ChatNotificationEventArgs e);
\r
64 /// Fired when a tab is selected
\r
66 public event ChatNotificationCallback OnChatNotification;
\r
69 /// Fired when a new tab is added
\r
71 public event TabCallback OnTabAdded;
\r
74 /// Fired when a tab is removed
\r
76 public event TabCallback OnTabRemoved;
\r
78 private RadegastInstance instance;
\r
79 private GridClient client { get { return instance.Client; } }
\r
80 private RadegastNetcom netcom { get { return instance.Netcom; } }
\r
81 private ChatTextManager mainChatManger;
\r
83 private Dictionary<string, RadegastTab> tabs = new Dictionary<string, RadegastTab>();
\r
84 public Dictionary<string, RadegastTab> Tabs { get { return tabs; } }
\r
86 private ChatConsole chatConsole;
\r
88 private RadegastTab selectedTab;
\r
91 /// Currently selected tab
\r
93 public RadegastTab SelectedTab
\r
101 private Form owner;
\r
103 public TabsConsole(RadegastInstance instance)
\r
105 InitializeComponent();
\r
106 Disposed += new EventHandler(TabsConsole_Disposed);
\r
108 this.instance = instance;
\r
109 this.instance.ClientChanged += new EventHandler<ClientChangedEventArgs>(instance_ClientChanged);
\r
113 InitializeMainTab();
\r
114 InitializeChatTab();
\r
117 RegisterClientEvents(client);
\r
120 private void RegisterClientEvents(GridClient client)
\r
122 client.Self.ScriptQuestion += new EventHandler<ScriptQuestionEventArgs>(Self_ScriptQuestion);
\r
123 client.Self.ScriptDialog += new EventHandler<ScriptDialogEventArgs>(Self_ScriptDialog);
\r
126 private void UnregisterClientEvents(GridClient client)
\r
128 client.Self.ScriptQuestion -= new EventHandler<ScriptQuestionEventArgs>(Self_ScriptQuestion);
\r
129 client.Self.ScriptDialog -= new EventHandler<ScriptDialogEventArgs>(Self_ScriptDialog);
\r
132 void instance_ClientChanged(object sender, ClientChangedEventArgs e)
\r
134 UnregisterClientEvents(e.OldClient);
\r
135 RegisterClientEvents(client);
\r
138 void TabsConsole_Disposed(object sender, EventArgs e)
\r
140 RemoveNetcomEvents();
\r
141 UnregisterClientEvents(client);
\r
144 private void AddNetcomEvents()
\r
146 netcom.ClientLoginStatus += new EventHandler<LoginProgressEventArgs>(netcom_ClientLoginStatus);
\r
147 netcom.ClientLoggedOut += new EventHandler(netcom_ClientLoggedOut);
\r
148 netcom.ClientDisconnected += new EventHandler<DisconnectedEventArgs>(netcom_ClientDisconnected);
\r
149 netcom.ChatReceived += new EventHandler<ChatEventArgs>(netcom_ChatReceived);
\r
150 netcom.ChatSent += new EventHandler<ChatSentEventArgs>(netcom_ChatSent);
\r
151 netcom.AlertMessageReceived += new EventHandler<AlertMessageEventArgs>(netcom_AlertMessageReceived);
\r
152 netcom.InstantMessageReceived += new EventHandler<InstantMessageEventArgs>(netcom_InstantMessageReceived);
\r
155 private void RemoveNetcomEvents()
\r
157 netcom.ClientLoginStatus -= new EventHandler<LoginProgressEventArgs>(netcom_ClientLoginStatus);
\r
158 netcom.ClientLoggedOut -= new EventHandler(netcom_ClientLoggedOut);
\r
159 netcom.ClientDisconnected -= new EventHandler<DisconnectedEventArgs>(netcom_ClientDisconnected);
\r
160 netcom.ChatReceived -= new EventHandler<ChatEventArgs>(netcom_ChatReceived);
\r
161 netcom.ChatSent -= new EventHandler<ChatSentEventArgs>(netcom_ChatSent);
\r
162 netcom.AlertMessageReceived -= new EventHandler<AlertMessageEventArgs>(netcom_AlertMessageReceived);
\r
163 netcom.InstantMessageReceived -= new EventHandler<InstantMessageEventArgs>(netcom_InstantMessageReceived);
\r
166 void Self_ScriptDialog(object sender, ScriptDialogEventArgs e)
\r
168 instance.MainForm.AddNotification(new ntfScriptDialog(instance, e.Message, e.ObjectName, e.ImageID, e.ObjectID, e.FirstName, e.LastName, e.Channel, e.ButtonLabels));
\r
171 void Self_ScriptQuestion(object sender, ScriptQuestionEventArgs e)
\r
173 instance.MainForm.AddNotification(new ntfPermissions(instance, e.Simulator, e.TaskID, e.ItemID, e.ObjectName, e.ObjectOwnerName, e.Questions));
\r
176 private void netcom_ClientLoginStatus(object sender, LoginProgressEventArgs e)
\r
178 if (e.Status == LoginStatus.Failed)
\r
180 DisplayNotificationInChat("Login error: " + e.Message, ChatBufferTextStyle.Error);
\r
182 else if (e.Status == LoginStatus.Success)
\r
184 DisplayNotificationInChat("Logged in as " + netcom.LoginOptions.FullName + ".", ChatBufferTextStyle.StatusDarkBlue);
\r
185 DisplayNotificationInChat("Login reply: " + e.Message, ChatBufferTextStyle.StatusDarkBlue);
\r
187 InitializeOnlineTabs();
\r
189 if (tabs.ContainsKey("login"))
\r
191 if (selectedTab.Name == "login")
\r
192 SelectDefaultTab();
\r
193 ForceCloseTab("login");
\r
196 client.Self.RetrieveInstantMessages();
\r
200 private void netcom_ClientLoggedOut(object sender, EventArgs e)
\r
202 DisposeOnlineTabs();
\r
204 SelectDefaultTab();
\r
205 DisplayNotificationInChat("Logged out.");
\r
209 private void netcom_ClientDisconnected(object sender, DisconnectedEventArgs e)
\r
211 if (e.Reason == NetworkManager.DisconnectType.ClientInitiated) return;
\r
213 DisposeOnlineTabs();
\r
214 SelectDefaultTab();
\r
215 DisplayNotificationInChat("Disconnected: " + e.Message, ChatBufferTextStyle.Error);
\r
218 private void netcom_AlertMessageReceived(object sender, AlertMessageEventArgs e)
\r
220 tabs["chat"].Highlight();
\r
223 private void netcom_ChatSent(object sender, ChatSentEventArgs e)
\r
225 tabs["chat"].Highlight();
\r
228 private void netcom_ChatReceived(object sender, ChatEventArgs e)
\r
230 if (string.IsNullOrEmpty(e.Message)) return;
\r
232 tabs["chat"].Highlight();
\r
235 private void netcom_InstantMessageReceived(object sender, InstantMessageEventArgs e)
\r
237 switch (e.IM.Dialog)
\r
239 case InstantMessageDialog.SessionSend:
\r
240 if (instance.Groups.ContainsKey(e.IM.IMSessionID))
\r
246 HandleConferenceIM(e);
\r
250 case InstantMessageDialog.MessageFromAgent:
\r
251 if (e.IM.FromAgentName == "Second Life")
\r
253 HandleIMFromObject(e);
\r
255 else if (e.IM.GroupIM || instance.Groups.ContainsKey(e.IM.IMSessionID))
\r
259 else if (e.IM.BinaryBucket.Length > 1)
\r
261 HandleConferenceIM(e);
\r
269 case InstantMessageDialog.MessageFromObject:
\r
270 HandleIMFromObject(e);
\r
273 case InstantMessageDialog.StartTyping:
\r
274 if (TabExists(e.IM.FromAgentName))
\r
276 RadegastTab tab = tabs[e.IM.FromAgentName.ToLower()];
\r
277 if (!tab.Highlighted) tab.PartialHighlight();
\r
282 case InstantMessageDialog.StopTyping:
\r
283 if (TabExists(e.IM.FromAgentName))
\r
285 RadegastTab tab = tabs[e.IM.FromAgentName.ToLower()];
\r
286 if (!tab.Highlighted) tab.Unhighlight();
\r
291 case InstantMessageDialog.MessageBox:
\r
292 instance.MainForm.AddNotification(new ntfGeneric(instance, e.IM.Message));
\r
295 case InstantMessageDialog.RequestTeleport:
\r
296 if (instance.RLV.AutoAcceptTP(e.IM.FromAgentID))
\r
298 DisplayNotificationInChat("Auto accepting teleprot from " + e.IM.FromAgentName);
\r
299 instance.Client.Self.TeleportLureRespond(e.IM.FromAgentID, true);
\r
303 instance.MainForm.AddNotification(new ntfTeleport(instance, e.IM));
\r
307 case InstantMessageDialog.GroupInvitation:
\r
308 instance.MainForm.AddNotification(new ntfGroupInvitation(instance, e.IM));
\r
311 case InstantMessageDialog.FriendshipOffered:
\r
312 instance.MainForm.AddNotification(new ntfFriendshipOffer(instance, e.IM));
\r
315 case InstantMessageDialog.InventoryAccepted:
\r
316 DisplayNotificationInChat(e.IM.FromAgentName + " accepted your inventory offer.");
\r
319 case InstantMessageDialog.InventoryDeclined:
\r
320 DisplayNotificationInChat(e.IM.FromAgentName + " declined your inventory offer.");
\r
323 case InstantMessageDialog.GroupNotice:
\r
324 instance.MainForm.AddNotification(new ntfGroupNotice(instance, e.IM));
\r
327 case InstantMessageDialog.InventoryOffered:
\r
328 case InstantMessageDialog.TaskInventoryOffered:
\r
329 instance.MainForm.AddNotification(new ntfInventoryOffer(instance, e.IM));
\r
335 /// Make default tab (chat) active
\r
337 public void SelectDefaultTab()
\r
339 if (TabExists("chat"))
\r
340 tabs["chat"].Select();
\r
344 /// Displays notification in the main chat tab
\r
346 /// <param name="msg">Message to be printed in the chat tab</param>
\r
347 public void DisplayNotificationInChat(string msg)
\r
349 DisplayNotificationInChat(msg, ChatBufferTextStyle.ObjectChat);
\r
353 /// Displays notification in the main chat tab
\r
355 /// <param name="msg">Message to be printed in the chat tab</param>
\r
356 /// <param name="style">Style of the message to be printed, normal, object, etc.</param>
\r
357 public void DisplayNotificationInChat(string msg, ChatBufferTextStyle style)
\r
359 DisplayNotificationInChat(msg, style, true);
\r
363 /// Displays notification in the main chat tab
\r
365 /// <param name="msg">Message to be printed in the chat tab</param>
\r
366 /// <param name="style">Style of the message to be printed, normal, object, etc.</param>
\r
367 /// <param name="highlightChatTab">Highligt (and flash in taskbar) chat tab if not selected</param>
\r
368 public void DisplayNotificationInChat(string msg, ChatBufferTextStyle style, bool highlightChatTab)
\r
370 if (InvokeRequired)
\r
372 BeginInvoke(new MethodInvoker(() => DisplayNotificationInChat(msg, style, highlightChatTab)));
\r
376 if (style != ChatBufferTextStyle.Invisible)
\r
378 ChatBufferItem line = new ChatBufferItem(
\r
386 mainChatManger.ProcessBufferItem(line, true);
\r
387 if (highlightChatTab)
\r
389 tabs["chat"].Highlight();
\r
392 catch (Exception) { }
\r
395 if (OnChatNotification != null)
\r
397 try { OnChatNotification(this, new ChatNotificationEventArgs(msg, style)); }
\r
402 private void HandleIMFromObject(InstantMessageEventArgs e)
\r
404 DisplayNotificationInChat(e.IM.FromAgentName + ": " + e.IM.Message);
\r
407 private void HandleIM(InstantMessageEventArgs e)
\r
409 if (TabExists(e.IM.IMSessionID.ToString()))
\r
411 RadegastTab tab = tabs[e.IM.IMSessionID.ToString()];
\r
412 if (!tab.Selected) tab.Highlight();
\r
416 IMTabWindow imTab = AddIMTab(e);
\r
417 tabs[e.IM.IMSessionID.ToString()].Highlight();
\r
420 private void HandleConferenceIM(InstantMessageEventArgs e)
\r
422 if (TabExists(e.IM.IMSessionID.ToString()))
\r
424 RadegastTab tab = tabs[e.IM.IMSessionID.ToString()];
\r
425 if (!tab.Selected) tab.Highlight();
\r
429 ConferenceIMTabWindow imTab = AddConferenceIMTab(e);
\r
430 tabs[e.IM.IMSessionID.ToString()].Highlight();
\r
433 private void HandleGroupIM(InstantMessageEventArgs e)
\r
435 if (TabExists(e.IM.IMSessionID.ToString()))
\r
437 RadegastTab tab = tabs[e.IM.IMSessionID.ToString()];
\r
438 if (!tab.Selected) tab.Highlight();
\r
442 GroupIMTabWindow imTab = AddGroupIMTab(e);
\r
443 tabs[e.IM.IMSessionID.ToString()].Highlight();
\r
446 private void InitializeMainTab()
\r
448 LoginConsole loginConsole = new LoginConsole(instance);
\r
450 RadegastTab tab = AddTab("login", "Login", loginConsole);
\r
451 tab.AllowClose = false;
\r
452 tab.AllowDetach = false;
\r
453 tab.AllowMerge = false;
\r
454 tab.AllowHide = false;
\r
456 loginConsole.RegisterTab(tab);
\r
459 private void InitializeChatTab()
\r
461 chatConsole = new ChatConsole(instance);
\r
462 mainChatManger = chatConsole.ChatManager;
\r
464 RadegastTab tab = AddTab("chat", "Chat", chatConsole);
\r
465 tab.AllowClose = false;
\r
466 tab.AllowDetach = false;
\r
467 tab.AllowHide = false;
\r
472 /// Create Tabs that only make sense when connected
\r
474 private void InitializeOnlineTabs()
\r
476 RadegastTab tab = AddTab("friends", "Friends", new FriendsConsole(instance));
\r
477 tab.AllowClose = false;
\r
478 tab.AllowDetach = true;
\r
479 tab.Visible = false;
\r
481 tab = AddTab("groups", "Groups", new GroupsConsole(instance));
\r
482 tab.AllowClose = false;
\r
483 tab.AllowDetach = true;
\r
484 tab.Visible = false;
\r
486 tab = AddTab("inventory", "Inventory", new InventoryConsole(instance));
\r
487 tab.AllowClose = false;
\r
488 tab.AllowDetach = true;
\r
489 tab.Visible = false;
\r
491 tab = AddTab("search", "Search", new SearchConsole(instance));
\r
492 tab.AllowClose = false;
\r
493 tab.AllowDetach = true;
\r
494 tab.Visible = false;
\r
496 if (!TabExists("map"))
\r
498 tab = AddTab("map", "Map", new MapConsole(instance));
\r
499 tab.AllowClose = false;
\r
500 tab.AllowDetach = true;
\r
501 tab.Visible = false;
\r
504 tab = AddTab("voice", "Voice", new VoiceConsole(instance));
\r
505 tab.AllowClose = false;
\r
506 tab.AllowDetach = true;
\r
507 tab.Visible = false;
\r
511 /// Close tabs that make no sense when not connected
\r
513 private void DisposeOnlineTabs()
\r
517 ForceCloseTab("voice");
\r
519 // Mono crashes if we try to open map for the second time
\r
520 if (!instance.MonoRuntime)
\r
521 ForceCloseTab("map");
\r
522 else if (TabExists("map"))
\r
523 tabs["map"].Hide();
\r
525 ForceCloseTab("search");
\r
526 ForceCloseTab("inventory");
\r
527 ForceCloseTab("groups");
\r
528 ForceCloseTab("friends");
\r
532 private void ForceCloseTab(string name)
\r
534 if (!TabExists(name)) return;
\r
536 RadegastTab tab = tabs[name];
\r
537 if (tab.Merged) SplitTab(tab);
\r
539 tab.AllowClose = true;
\r
545 public void RegisterContextAction(Type libomvType, String label, EventHandler handler)
\r
547 instance.ContextActionManager.RegisterContextAction(libomvType, label, handler);
\r
550 public void RegisterContextAction(ContextAction handler)
\r
552 instance.ContextActionManager.RegisterContextAction(handler);
\r
555 public void AddTab(RadegastTab tab)
\r
557 ToolStripButton button = (ToolStripButton)tstTabs.Items.Add(tab.Label);
\r
558 button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
\r
559 button.Image = null;
\r
560 button.AutoToolTip = false;
\r
561 button.Tag = tab.Name;
\r
562 button.Click += new EventHandler(TabButtonClick);
\r
563 tab.Button = button;
\r
564 tabs.Add(tab.Name, tab);
\r
566 if (OnTabAdded != null)
\r
568 try { OnTabAdded(this, new TabEventArgs(tab)); }
\r
569 catch (Exception) { }
\r
573 public RadegastTab AddTab(string name, string label, Control control)
\r
575 // WORKAROUND: one should never add tab that alrady exists
\r
576 // but under some weird conditions disconnect/connect
\r
577 // fire in the wrong order
\r
578 if (TabExists(name))
\r
580 Logger.Log("Force closing tab '" + name + "'", Helpers.LogLevel.Warning, client);
\r
581 ForceCloseTab(name);
\r
584 control.Visible = false;
\r
585 control.Dock = DockStyle.Fill;
\r
586 toolStripContainer1.ContentPanel.Controls.Add(control);
\r
588 ToolStripButton button = (ToolStripButton)tstTabs.Items.Add(label);
\r
589 button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
\r
590 button.Image = null;
\r
591 button.AutoToolTip = false;
\r
592 button.Tag = name.ToLower();
\r
593 button.Click += new EventHandler(TabButtonClick);
\r
595 RadegastTab tab = new RadegastTab(instance, button, control, name.ToLower(), label);
\r
596 tab.TabAttached += new EventHandler(tab_TabAttached);
\r
597 tab.TabDetached += new EventHandler(tab_TabDetached);
\r
598 tab.TabSelected += new EventHandler(tab_TabSelected);
\r
599 tab.TabClosed += new EventHandler(tab_TabClosed);
\r
600 tab.TabHidden += new EventHandler(tab_TabHidden);
\r
601 tabs.Add(name.ToLower(), tab);
\r
603 if (OnTabAdded != null)
\r
605 try { OnTabAdded(this, new TabEventArgs(tab)); }
\r
606 catch (Exception) { }
\r
612 private void tab_TabAttached(object sender, EventArgs e)
\r
614 RadegastTab tab = (RadegastTab)sender;
\r
618 private void tab_TabDetached(object sender, EventArgs e)
\r
620 RadegastTab tab = (RadegastTab)sender;
\r
621 frmDetachedTab form = (frmDetachedTab)tab.Owner;
\r
623 form.ReattachStrip = tstTabs;
\r
624 form.ReattachContainer = toolStripContainer1.ContentPanel;
\r
627 private void tab_TabSelected(object sender, EventArgs e)
\r
629 RadegastTab tab = (RadegastTab)sender;
\r
631 if (selectedTab != null &&
\r
632 selectedTab != tab)
\r
633 { selectedTab.Deselect(); }
\r
637 tbtnCloseTab.Enabled = tab.AllowClose || tab.AllowHide;
\r
638 owner.AcceptButton = tab.DefaultControlButton;
\r
640 if (OnTabSelected != null)
\r
642 try { OnTabSelected(this, new TabEventArgs(selectedTab)); }
\r
643 catch (Exception) { }
\r
647 void tab_TabHidden(object sender, EventArgs e)
\r
649 RadegastTab tab = (RadegastTab)sender;
\r
651 if (selectedTab != null && selectedTab == tab)
\r
654 SelectDefaultTab();
\r
658 private void tab_TabClosed(object sender, EventArgs e)
\r
660 RadegastTab tab = (RadegastTab)sender;
\r
662 if (selectedTab != null && selectedTab == tab && tab.Name != "chat")
\r
665 SelectDefaultTab();
\r
668 tabs.Remove(tab.Name);
\r
670 if (OnTabRemoved != null)
\r
672 try { OnTabRemoved(this, new TabEventArgs(tab)); }
\r
673 catch (Exception) { }
\r
679 private void TabButtonClick(object sender, EventArgs e)
\r
681 ToolStripButton button = (ToolStripButton)sender;
\r
683 RadegastTab tab = tabs[button.Tag.ToString()];
\r
687 public void RemoveTabEntry(RadegastTab tab)
\r
689 if (tstTabs.Items.Contains(tab.Button))
\r
691 tstTabs.Items.Remove(tab.Button);
\r
694 tab.Button.Dispose();
\r
695 tabs.Remove(tab.Name);
\r
698 public void RemoveTab(string name)
\r
700 if (tabs.ContainsKey(name))
\r
706 //Used for outside classes that have a reference to TabsConsole
\r
707 public void SelectTab(string name)
\r
709 tabs[name.ToLower()].Select();
\r
712 public bool TabExists(string name)
\r
714 return tabs.ContainsKey(name.ToLower());
\r
717 public RadegastTab GetTab(string name)
\r
719 return tabs[name.ToLower()];
\r
722 public List<RadegastTab> GetOtherTabs()
\r
724 List<RadegastTab> otherTabs = new List<RadegastTab>();
\r
726 foreach (ToolStripItem item in tstTabs.Items)
\r
728 if (item.Tag == null) continue;
\r
729 if ((ToolStripItem)item == selectedTab.Button) continue;
\r
731 RadegastTab tab = tabs[item.Tag.ToString()];
\r
732 if (!tab.AllowMerge) continue;
\r
733 if (tab.Merged) continue;
\r
735 otherTabs.Add(tab);
\r
742 /// Activates the next tab
\r
744 public void SelectNextTab()
\r
746 List<ToolStripItem> buttons = new List<ToolStripItem>();
\r
748 foreach (ToolStripItem item in tstTabs.Items)
\r
750 if (item.Tag == null || !item.Visible) continue;
\r
757 for (int i = 0; i < buttons.Count; i++)
\r
759 if (buttons[i] == selectedTab.Button)
\r
768 if (current == buttons.Count)
\r
771 SelectTab(tabs[buttons[current].Tag.ToString()].Name);
\r
775 /// Activates the previous tab
\r
777 public void SelectPreviousTab()
\r
779 List<ToolStripItem> buttons = new List<ToolStripItem>();
\r
781 foreach (ToolStripItem item in tstTabs.Items)
\r
783 if (item.Tag == null || !item.Visible) continue;
\r
790 for (int i = 0; i < buttons.Count; i++)
\r
792 if (buttons[i] == selectedTab.Button)
\r
802 current = buttons.Count - 1;
\r
804 SelectTab(tabs[buttons[current].Tag.ToString()].Name);
\r
808 public IMTabWindow AddIMTab(UUID target, UUID session, string targetName)
\r
810 IMTabWindow imTab = new IMTabWindow(instance, target, session, targetName);
\r
812 RadegastTab tab = AddTab(session.ToString(), "IM: " + targetName, imTab);
\r
813 imTab.SelectIMInput();
\r
819 public ConferenceIMTabWindow AddConferenceIMTab(UUID session, string name)
\r
821 ConferenceIMTabWindow imTab = new ConferenceIMTabWindow(instance, session, name);
\r
823 RadegastTab tab = AddTab(session.ToString(), name, imTab);
\r
824 imTab.SelectIMInput();
\r
830 public ConferenceIMTabWindow AddConferenceIMTab(InstantMessageEventArgs e)
\r
832 ConferenceIMTabWindow imTab = AddConferenceIMTab(e.IM.IMSessionID, Utils.BytesToString(e.IM.BinaryBucket));
\r
833 imTab.TextManager.ProcessIM(e);
\r
837 public GroupIMTabWindow AddGroupIMTab(UUID session, string name)
\r
839 GroupIMTabWindow imTab = new GroupIMTabWindow(instance, session, name);
\r
841 RadegastTab tab = AddTab(session.ToString(), name, imTab);
\r
842 imTab.SelectIMInput();
\r
847 public GroupIMTabWindow AddGroupIMTab(InstantMessageEventArgs e)
\r
849 GroupIMTabWindow imTab = AddGroupIMTab(e.IM.IMSessionID, Utils.BytesToString(e.IM.BinaryBucket));
\r
850 imTab.TextManager.ProcessIM(e);
\r
854 public IMTabWindow AddIMTab(InstantMessageEventArgs e)
\r
856 IMTabWindow imTab = AddIMTab(e.IM.FromAgentID, e.IM.IMSessionID, e.IM.FromAgentName);
\r
857 imTab.TextManager.ProcessIM(e);
\r
861 public OutfitTextures AddOTTab(Avatar avatar)
\r
863 OutfitTextures otTab = new OutfitTextures(instance, avatar);
\r
865 RadegastTab tab = AddTab("OT: " + avatar.Name, "OT: " + avatar.Name, otTab);
\r
866 otTab.GetTextures();
\r
870 public MasterTab AddMSTab(Avatar avatar)
\r
872 MasterTab msTab = new MasterTab(instance, avatar);
\r
874 RadegastTab tab = AddTab("MS: " + avatar.Name, "MS: " + avatar.Name, msTab);
\r
878 public AttachmentTab AddATTab(Avatar avatar)
\r
880 AttachmentTab atTab = new AttachmentTab(instance, avatar);
\r
882 RadegastTab tab = AddTab("AT: " + avatar.Name, "AT: " + avatar.Name, atTab);
\r
886 public AnimTab AddAnimTab(Avatar avatar)
\r
888 AnimTab animTab = new AnimTab(instance, avatar);
\r
890 RadegastTab tab = AddTab("Anim: " + avatar.Name, "Anim: " + avatar.Name, animTab);
\r
894 private void tbtnTabOptions_Click(object sender, EventArgs e)
\r
896 tmnuMergeWith.Enabled = selectedTab.AllowMerge;
\r
897 tmnuDetachTab.Enabled = selectedTab.AllowDetach;
\r
899 tmnuMergeWith.DropDown.Items.Clear();
\r
901 if (!selectedTab.AllowMerge) return;
\r
902 if (!selectedTab.Merged)
\r
904 tmnuMergeWith.Text = "Merge With";
\r
906 List<RadegastTab> otherTabs = GetOtherTabs();
\r
908 tmnuMergeWith.Enabled = (otherTabs.Count > 0);
\r
909 if (!tmnuMergeWith.Enabled) return;
\r
911 foreach (RadegastTab tab in otherTabs)
\r
913 ToolStripItem item = tmnuMergeWith.DropDown.Items.Add(tab.Label);
\r
914 item.Tag = tab.Name;
\r
915 item.Click += new EventHandler(MergeItemClick);
\r
920 tmnuMergeWith.Text = "Split";
\r
921 tmnuMergeWith.Click += new EventHandler(SplitClick);
\r
925 private void MergeItemClick(object sender, EventArgs e)
\r
927 ToolStripItem item = (ToolStripItem)sender;
\r
928 RadegastTab tab = tabs[item.Tag.ToString()];
\r
930 selectedTab.MergeWith(tab);
\r
932 SplitContainer container = (SplitContainer)selectedTab.Control;
\r
933 toolStripContainer1.ContentPanel.Controls.Add(container);
\r
935 selectedTab.Select();
\r
936 RemoveTabEntry(tab);
\r
938 tabs.Add(tab.Name, selectedTab);
\r
941 private void SplitClick(object sender, EventArgs e)
\r
943 SplitTab(selectedTab);
\r
944 selectedTab.Select();
\r
947 public void SplitTab(RadegastTab tab)
\r
949 RadegastTab otherTab = tab.Split();
\r
950 if (otherTab == null) return;
\r
952 toolStripContainer1.ContentPanel.Controls.Add(tab.Control);
\r
953 toolStripContainer1.ContentPanel.Controls.Add(otherTab.Control);
\r
955 tabs.Remove(otherTab.Name);
\r
959 private void tmnuDetachTab_Click(object sender, EventArgs e)
\r
961 if (!selectedTab.AllowDetach) return;
\r
962 RadegastTab tab = selectedTab;
\r
963 SelectDefaultTab();
\r
964 tab.Detach(instance);
\r
967 private void tbtnCloseTab_Click(object sender, EventArgs e)
\r
969 RadegastTab tab = selectedTab;
\r
970 if (tab.AllowClose)
\r
972 else if (tab.AllowHide)
\r
976 private void TabsConsole_Load(object sender, EventArgs e)
\r
978 owner = this.FindForm();
\r
981 private void ctxTabs_Opening(object sender, CancelEventArgs e)
\r
983 Point pt = this.PointToClient(Cursor.Position);
\r
984 ToolStripItem stripItem = tstTabs.GetItemAt(pt);
\r
986 if (stripItem == null)
\r
992 tabs[stripItem.Tag.ToString()].Select();
\r
994 ctxBtnClose.Enabled = selectedTab.AllowClose || selectedTab.AllowHide;
\r
995 ctxBtnDetach.Enabled = selectedTab.AllowDetach;
\r
996 ctxBtnMerge.Enabled = selectedTab.AllowMerge;
\r
997 ctxBtnMerge.DropDown.Items.Clear();
\r
999 if (!ctxBtnClose.Enabled && !ctxBtnDetach.Enabled && !ctxBtnMerge.Enabled)
\r
1005 if (!selectedTab.AllowMerge) return;
\r
1006 if (!selectedTab.Merged)
\r
1008 ctxBtnMerge.Text = "Merge With";
\r
1010 List<RadegastTab> otherTabs = GetOtherTabs();
\r
1012 ctxBtnMerge.Enabled = (otherTabs.Count > 0);
\r
1013 if (!ctxBtnMerge.Enabled) return;
\r
1015 foreach (RadegastTab tab in otherTabs)
\r
1017 ToolStripItem item = ctxBtnMerge.DropDown.Items.Add(tab.Label);
\r
1018 item.Tag = tab.Name;
\r
1019 item.Click += new EventHandler(MergeItemClick);
\r
1024 ctxBtnMerge.Text = "Split";
\r
1025 ctxBtnMerge.Click += new EventHandler(SplitClick);
\r
1034 /// Arguments for tab events
\r
1036 public class TabEventArgs : EventArgs
\r
1039 /// Tab that was manipulated in the event
\r
1041 public RadegastTab Tab;
\r
1043 public TabEventArgs()
\r
1048 public TabEventArgs(RadegastTab tab)
\r
1056 /// Argument for chat notification events
\r
1058 public class ChatNotificationEventArgs : EventArgs
\r
1060 public string Message;
\r
1061 public ChatBufferTextStyle Style;
\r
1063 public ChatNotificationEventArgs(string message, ChatBufferTextStyle style)
\r
1065 Message = message;
\r