2 // Radegast Metaverse Client
3 // Copyright (c) 2009-2013, Radegast Development Team
4 // All rights reserved.
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
9 // * Redistributions of source code must retain the above copyright notice,
10 // this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 // * Neither the name of the application "Radegast", nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 using System.Collections.Generic;
33 using System.Windows.Forms;
35 using System.Diagnostics;
39 public partial class SearchConsole : UserControl
41 #region Private members
42 private RadegastInstance instance;
43 private GridClient client { get { return instance.Client; } }
45 private FindPeopleConsole console;
47 private string lastQuery = string.Empty;
48 private int startResult = 0;
50 private int totalResults = 0;
51 #endregion Private members
53 #region Construction and disposal
54 public SearchConsole(RadegastInstance instance)
56 InitializeComponent();
57 Disposed += new EventHandler(SearchConsole_Disposed);
59 this.instance = instance;
61 comboEventType.SelectedIndex = 0;
62 lvwEvents.Parent.SizeChanged += lvwEvents_SizeChanged;
63 lvwEvents.ListViewItemSorter = new EventSorter();
66 client.Directory.DirPeopleReply += new EventHandler<DirPeopleReplyEventArgs>(Directory_DirPeopleReply);
67 client.Directory.DirPlacesReply += new EventHandler<DirPlacesReplyEventArgs>(Directory_DirPlacesReply);
68 client.Directory.DirGroupsReply += new EventHandler<DirGroupsReplyEventArgs>(Directory_DirGroupsReply);
69 client.Directory.DirEventsReply += Directory_DirEventsReply;
70 client.Directory.EventInfoReply += Directory_EventInfoReply;
71 instance.Names.NameUpdated += Names_NameUpdated;
72 console = new FindPeopleConsole(instance, UUID.Random());
73 console.Dock = DockStyle.Fill;
74 console.SelectedIndexChanged += new EventHandler(console_SelectedIndexChanged);
75 pnlFindPeople.Controls.Add(console);
76 lvwPlaces.ListViewItemSorter = new PlaceSorter();
77 lvwGroups.ListViewItemSorter = new GroupSorter();
80 void SearchConsole_Disposed(object sender, EventArgs e)
82 client.Directory.DirPeopleReply -= new EventHandler<DirPeopleReplyEventArgs>(Directory_DirPeopleReply);
83 client.Directory.DirPlacesReply -= new EventHandler<DirPlacesReplyEventArgs>(Directory_DirPlacesReply);
84 client.Directory.DirGroupsReply -= new EventHandler<DirGroupsReplyEventArgs>(Directory_DirGroupsReply);
85 client.Directory.DirEventsReply -= Directory_DirEventsReply;
86 client.Directory.EventInfoReply -= Directory_EventInfoReply;
87 instance.Names.NameUpdated -= Names_NameUpdated;
90 #endregion Construction and disposal
93 private void console_SelectedIndexChanged(object sender, EventArgs e)
95 btnNewIM.Enabled = btnProfile.Enabled = (console.SelectedName != null);
99 void Directory_DirPeopleReply(object sender, DirPeopleReplyEventArgs e)
103 BeginInvoke(new MethodInvoker(() => Directory_DirPeopleReply(sender, e)));
107 if (console.QueryID != e.QueryID) return;
109 totalResults += e.MatchedPeople.Count;
110 lblResultCount.Text = totalResults.ToString() + " people found";
112 txtPersonName.Enabled = true;
113 btnFind.Enabled = true;
115 btnNext.Enabled = (totalResults > 100);
116 btnPrevious.Enabled = (startResult > 0);
119 private void txtPersonName_TextChanged(object sender, EventArgs e)
121 btnFind.Enabled = (txtPersonName.Text.Trim().Length > 2);
124 private void btnNewIM_Click(object sender, EventArgs e)
126 instance.TabConsole.ShowIMTab(console.SelectedAgentUUID, console.SelectedName, true);
129 private void btnFind_Click(object sender, EventArgs e)
131 lastQuery = txtPersonName.Text;
136 private void txtPersonName_KeyUp(object sender, KeyEventArgs e)
138 if (e.KeyCode != Keys.Enter) return;
139 e.SuppressKeyPress = true;
140 if (txtPersonName.Text.Trim().Length < 3) return;
142 lastQuery = txtPersonName.Text;
147 private void StartFinding()
150 lblResultCount.Text = "Searching for " + lastQuery;
152 txtPersonName.Enabled = false;
153 btnFind.Enabled = false;
154 btnNewIM.Enabled = false;
155 btnProfile.Enabled = false;
156 btnPrevious.Enabled = false;
157 btnNext.Enabled = false;
159 console.ClearResults();
160 console.QueryID = client.Directory.StartPeopleSearch(/*
161 DirectoryManager.DirFindFlags.NameSort |
162 DirectoryManager.DirFindFlags.SortAsc |
163 DirectoryManager.DirFindFlags.People,*/
164 lastQuery, startResult);
167 private void btnNext_Click(object sender, EventArgs e)
173 private void btnPrevious_Click(object sender, EventArgs e)
179 private void btnProfile_Click(object sender, EventArgs e)
181 instance.MainForm.ShowAgentProfile(console.SelectedName, console.SelectedAgentUUID);
184 private void txtPersonName_KeyDown(object sender, KeyEventArgs e)
186 if (e.KeyCode == Keys.Enter) e.SuppressKeyPress = true;
189 private void btnLink_Click(object sender, EventArgs e)
191 ProcessStartInfo sInfo = new ProcessStartInfo(((Button)sender).Tag.ToString());
192 Process.Start(sInfo);
194 #endregion People search
196 #region Places search
197 private UUID placeSearch;
198 private int placeMatches = 0;
199 private int placeStart = 0;
201 void Directory_DirPlacesReply(object sender, DirPlacesReplyEventArgs e)
203 if (e.QueryID != placeSearch) return;
207 BeginInvoke(new MethodInvoker(() => Directory_DirPlacesReply(sender, e)));
211 lvwPlaces.BeginUpdate();
213 if (e.MatchedParcels.Count == 0)
214 lvwPlaces.Items.Clear();
216 foreach (DirectoryManager.DirectoryParcel parcel in e.MatchedParcels)
218 if (parcel.ID == UUID.Zero) continue;
220 ListViewItem item = new ListViewItem();
221 item.Name = parcel.ID.ToString();
222 item.Text = parcel.Name;
224 item.SubItems.Add(new ListViewItem.ListViewSubItem(item, parcel.Dwell.ToString()));
225 lvwPlaces.Items.Add(item);
228 lvwPlaces.EndUpdate();
230 placeMatches += e.MatchedParcels.Count;
232 btnNextPlace.Enabled = placeMatches > 100;
233 btnPrevPlace.Enabled = placeStart != 0;
235 if (e.MatchedParcels.Count > 0 && e.MatchedParcels[e.MatchedParcels.Count - 1].ID == UUID.Zero)
238 lblNrPlaces.Visible = true;
239 lblNrPlaces.Text = string.Format("{0} places found", placeMatches > 100 ? "More than " + (placeStart + 100).ToString() : (placeStart + placeMatches).ToString());
244 private void txtSearchPlace_KeyDown(object sender, KeyEventArgs e)
246 if (e.KeyCode == Keys.Enter)
247 e.SuppressKeyPress = true;
250 private void txtSearchPlace_KeyUp(object sender, KeyEventArgs e)
252 if (e.KeyCode == Keys.Enter)
254 e.SuppressKeyPress = true;
255 if (btnSearchPlace.Enabled)
257 btnSearchPlace_Click(null, EventArgs.Empty);
262 private void txtSearchPlace_TextChanged(object sender, EventArgs e)
264 if (txtSearchPlace.Text.Length > 0)
265 btnSearchPlace.Enabled = true;
267 btnSearchPlace.Enabled = false;
270 // StartPlacesSearch(DirFindFlags findFlags, ParcelCategory searchCategory, string searchText, string simulatorName, UUID groupID, UUID transactionID)
271 private void btnSearchPlace_Click(object sender, EventArgs e)
275 lvwPlaces.Items.Clear();
276 placeSearch = client.Directory.StartDirPlacesSearch(txtSearchPlace.Text.Trim(), 0);
279 private void btnNextPlace_Click(object sender, EventArgs e)
283 lvwPlaces.Items.Clear();
284 placeSearch = client.Directory.StartDirPlacesSearch(txtSearchPlace.Text.Trim(), placeStart);
287 private void btnPrevPlace_Click(object sender, EventArgs e)
291 lvwPlaces.Items.Clear();
292 placeSearch = client.Directory.StartDirPlacesSearch(txtSearchPlace.Text.Trim(), placeStart);
295 public class PlaceSorter : System.Collections.IComparer
297 public enum SortByColumn
303 public enum SortOrder
309 public SortOrder CurrentOrder = SortOrder.Descending;
310 public SortByColumn SortBy = SortByColumn.Traffic;
312 public int Compare(object x, object y)
314 ListViewItem item1 = (ListViewItem)x;
315 ListViewItem item2 = (ListViewItem)y;
316 DirectoryManager.DirectoryParcel member1 = (DirectoryManager.DirectoryParcel)item1.Tag;
317 DirectoryManager.DirectoryParcel member2 = (DirectoryManager.DirectoryParcel)item2.Tag;
321 case SortByColumn.Name:
322 if (CurrentOrder == SortOrder.Ascending)
323 return string.Compare(item1.Text, item2.Text);
325 return string.Compare(item2.Text, item1.Text);
327 case SortByColumn.Traffic:
328 if (CurrentOrder == SortOrder.Ascending)
330 if (member1.Dwell > member2.Dwell)
332 else if (member1.Dwell < member2.Dwell)
337 if (member1.Dwell > member2.Dwell)
339 else if (member1.Dwell < member2.Dwell)
349 private void lvwPlaces_ColumnClick(object sender, ColumnClickEventArgs e)
351 PlaceSorter sorter = (PlaceSorter)lvwPlaces.ListViewItemSorter;
355 sorter.SortBy = PlaceSorter.SortByColumn.Name;
359 sorter.SortBy = PlaceSorter.SortByColumn.Traffic;
363 if (sorter.CurrentOrder == PlaceSorter.SortOrder.Ascending)
364 sorter.CurrentOrder = PlaceSorter.SortOrder.Descending;
366 sorter.CurrentOrder = PlaceSorter.SortOrder.Ascending;
372 private void lvwPlaces_SelectedIndexChanged(object sender, EventArgs e)
374 for (int i = 0; i < pnlPlaceDetail.Controls.Count; i++)
376 pnlPlaceDetail.Controls[i].Dispose();
378 pnlPlaceDetail.Controls.Clear();
380 if (lvwPlaces.SelectedItems.Count == 1)
382 Landmark l = new Landmark(instance, ((DirectoryManager.DirectoryParcel)lvwPlaces.SelectedItems[0].Tag).ID);
383 l.Dock = DockStyle.Fill;
384 pnlPlaceDetail.Controls.Add(l);
387 #endregion Places search
389 #region Groups search
390 private UUID groupSearch;
391 private int groupMatches = 0;
392 private int groupStart = 0;
394 void Directory_DirGroupsReply(object sender, DirGroupsReplyEventArgs e)
396 if (e.QueryID != groupSearch) return;
400 BeginInvoke(new MethodInvoker(() => Directory_DirGroupsReply(sender, e)));
404 lvwGroups.BeginUpdate();
406 if (e.MatchedGroups.Count == 0)
407 lvwGroups.Items.Clear();
409 foreach (DirectoryManager.GroupSearchData group in e.MatchedGroups)
411 if (group.GroupID == UUID.Zero) continue;
413 ListViewItem item = new ListViewItem();
414 item.Name = group.GroupID.ToString();
415 item.Text = group.GroupName;
417 item.SubItems.Add(new ListViewItem.ListViewSubItem(item, group.Members.ToString()));
419 lvwGroups.Items.Add(item);
422 lvwGroups.EndUpdate();
424 groupMatches += e.MatchedGroups.Count;
425 btnNextGroup.Enabled = groupMatches > 100;
426 btnPrevGroup.Enabled = placeStart != 0;
428 if (e.MatchedGroups.Count > 0 && e.MatchedGroups[e.MatchedGroups.Count - 1].GroupID == UUID.Zero)
431 lblNrGroups.Visible = true;
432 lblNrGroups.Text = string.Format("{0} groups found", groupMatches > 100 ? "More than " + (groupStart + 100).ToString() : (groupStart + groupMatches).ToString());
435 private void btnSearchGroup_Click(object sender, EventArgs e)
439 lvwGroups.Items.Clear();
440 groupSearch = client.Directory.StartGroupSearch(txtSearchGroup.Text.Trim(), 0);
443 private void txtSearchGroup_KeyDown(object sender, KeyEventArgs e)
445 if (e.KeyCode == Keys.Enter)
447 e.SuppressKeyPress = e.Handled = true;
448 btnSearchGroup.PerformClick();
452 private void txtSearchGroup_TextChanged(object sender, EventArgs e)
454 if (txtSearchGroup.Text.Length > 1)
456 btnSearchGroup.Enabled = true;
460 btnSearchGroup.Enabled = false;
464 private void btnPrevGroup_Click(object sender, EventArgs e)
468 lvwGroups.Items.Clear();
469 groupSearch = client.Directory.StartGroupSearch(txtSearchGroup.Text.Trim(), groupStart);
472 private void btnNextGroup_Click(object sender, EventArgs e)
476 lvwGroups.Items.Clear();
477 groupSearch = client.Directory.StartGroupSearch(txtSearchGroup.Text.Trim(), groupStart);
480 private void lvwGroups_SelectedIndexChanged(object sender, EventArgs e)
482 foreach (Control c in pnlGroupDetail.Controls)
486 pnlGroupDetail.Controls.Clear();
488 if (lvwGroups.SelectedItems.Count == 1)
492 DirectoryManager.GroupSearchData g = (DirectoryManager.GroupSearchData)lvwGroups.SelectedItems[0].Tag;
493 GroupDetails grpPanel = new GroupDetails(instance, new Group() { ID = g.GroupID, Name = g.GroupName });
494 grpPanel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
495 grpPanel.Region = new System.Drawing.Region(
496 new System.Drawing.RectangleF(
497 grpPanel.tpGeneral.Left, grpPanel.tpGeneral.Top, grpPanel.tpGeneral.Width, grpPanel.tpGeneral.Height));
498 pnlGroupDetail.Controls.Add(grpPanel);
504 private void lvwGroups_ColumnClick(object sender, ColumnClickEventArgs e)
506 GroupSorter sorter = (GroupSorter)lvwGroups.ListViewItemSorter;
510 sorter.SortBy = GroupSorter.SortByColumn.Name;
514 sorter.SortBy = GroupSorter.SortByColumn.Members;
518 if (sorter.CurrentOrder == GroupSorter.SortOrder.Ascending)
519 sorter.CurrentOrder = GroupSorter.SortOrder.Descending;
521 sorter.CurrentOrder = GroupSorter.SortOrder.Ascending;
526 public class GroupSorter : System.Collections.IComparer
528 public enum SortByColumn
534 public enum SortOrder
540 public SortOrder CurrentOrder = SortOrder.Ascending;
541 public SortByColumn SortBy = SortByColumn.Name;
543 public int Compare(object x, object y)
545 ListViewItem item1 = (ListViewItem)x;
546 ListViewItem item2 = (ListViewItem)y;
547 DirectoryManager.GroupSearchData group1 = (DirectoryManager.GroupSearchData)item1.Tag;
548 DirectoryManager.GroupSearchData group2 = (DirectoryManager.GroupSearchData)item2.Tag;
552 case SortByColumn.Name:
553 if (CurrentOrder == SortOrder.Ascending)
554 return string.Compare(item1.Text, item2.Text);
556 return string.Compare(item2.Text, item1.Text);
558 case SortByColumn.Members:
559 if (CurrentOrder == SortOrder.Ascending)
561 if (group1.Members > group2.Members)
563 else if (group1.Members < group2.Members)
568 if (group1.Members > group2.Members)
570 else if (group1.Members < group2.Members)
579 #endregion Groups search
581 #region Events Search
583 uint eventsPerPage = 200;
588 DirectoryManager.EventCategories eventType;
589 DirectoryManager.DirFindFlags eventFlags;
590 string eventTime = "u";
592 static Dictionary<int, DirectoryManager.EventCategories> eventTypeMap = new Dictionary<int, DirectoryManager.EventCategories>(12);
594 void Directory_DirEventsReply(object sender, DirEventsReplyEventArgs e)
596 if (e.QueryID != eventSearch) return;
600 BeginInvoke(new MethodInvoker(() => Directory_DirEventsReply(sender, e)));
604 lvwEvents.BeginUpdate();
606 foreach (var evt in e.MatchedEvents)
608 if (evt.ID == 0) continue;
610 ListViewItem item = new ListViewItem();
611 item.Name = "evt" + evt.ID.ToString();
612 item.Text = evt.Name;
614 item.SubItems.Add(new ListViewItem.ListViewSubItem(item, evt.Date));
616 lvwEvents.Items.Add(item);
620 lvwEvents.EndUpdate();
622 eventMatches += e.MatchedEvents.Count;
623 btnNextEvent.Enabled = eventMatches > eventsPerPage;
624 btnPrevEvent.Enabled = eventStart != 0;
626 if (e.MatchedEvents.Count > 0 && e.MatchedEvents[e.MatchedEvents.Count - 1].ID == 0)
629 lblNrEvents.Visible = true;
630 lblNrEvents.Text = string.Format("{0} events found", eventMatches > eventsPerPage ? "More than " + (eventStart + eventsPerPage).ToString() : (eventStart + eventMatches).ToString());
634 private void btnSearchEvents_Click(object sender, EventArgs e)
636 if (eventTypeMap.Count == 0)
638 eventTypeMap[1] = DirectoryManager.EventCategories.Discussion;
639 eventTypeMap[2] = DirectoryManager.EventCategories.Sports;
640 eventTypeMap[3] = DirectoryManager.EventCategories.LiveMusic;
641 eventTypeMap[4] = DirectoryManager.EventCategories.Commercial;
642 eventTypeMap[5] = DirectoryManager.EventCategories.Nightlife;
643 eventTypeMap[6] = DirectoryManager.EventCategories.Games;
644 eventTypeMap[7] = DirectoryManager.EventCategories.Pageants;
645 eventTypeMap[8] = DirectoryManager.EventCategories.Education;
646 eventTypeMap[9] = DirectoryManager.EventCategories.Arts;
647 eventTypeMap[10] = DirectoryManager.EventCategories.Charity;
648 eventTypeMap[11] = DirectoryManager.EventCategories.Miscellaneous;
651 eventType = DirectoryManager.EventCategories.All;
653 if (eventTypeMap.ContainsKey(comboEventType.SelectedIndex))
655 eventType = eventTypeMap[comboEventType.SelectedIndex];
659 eventFlags = DirectoryManager.DirFindFlags.DateEvents |
660 DirectoryManager.DirFindFlags.IncludePG |
661 DirectoryManager.DirFindFlags.IncludeMature |
662 DirectoryManager.DirFindFlags.IncludeAdult;
666 PerformEventSearch();
669 void PerformEventSearch()
671 lvwEvents_SizeChanged(this, EventArgs.Empty);
672 lvwEvents.Items.Clear();
673 eventSearch = client.Directory.StartEventsSearch(txtSearchEvents.Text.Trim(), eventFlags, eventTime, eventStart, eventType);
676 private void btnSearchEvents_KeyDown(object sender, KeyEventArgs e)
678 if (e.KeyCode == Keys.Enter)
680 e.SuppressKeyPress = e.Handled = true;
681 btnSearchEvents.PerformClick();
685 private void btnPrevEvent_Click(object sender, EventArgs e)
688 eventStart -= eventsPerPage;
689 PerformEventSearch();
692 private void btnNextEvent_Click(object sender, EventArgs e)
695 eventStart += eventsPerPage;
696 PerformEventSearch();
699 void lvwEvents_SizeChanged(object sender, EventArgs e)
701 lvwEvents.Columns[0].Width = lvwEvents.Width - 130;
704 class EventSorter : System.Collections.IComparer
706 public int Compare(object a, object b)
710 DirectoryManager.EventsSearchData e1 = (DirectoryManager.EventsSearchData)((ListViewItem)a).Tag;
711 DirectoryManager.EventsSearchData e2 = (DirectoryManager.EventsSearchData)((ListViewItem)b).Tag;
713 if (e1.Time < e2.Time) return -1;
714 else if (e1.Time > e2.Time) return 1;
715 else return string.Compare(e1.Name, e2.Name);
722 private void lvwEvents_SelectedIndexChanged(object sender, EventArgs e)
724 pnlEventDetail.Visible = false;
726 if (lvwEvents.SelectedItems.Count == 1 && (lvwEvents.SelectedItems[0].Tag is DirectoryManager.EventsSearchData))
728 var evt = (DirectoryManager.EventsSearchData)lvwEvents.SelectedItems[0].Tag;
729 client.Directory.EventInfoRequest(evt.ID);
733 void Directory_EventInfoReply(object sender, EventInfoReplyEventArgs e)
737 BeginInvoke(new MethodInvoker(() => Directory_EventInfoReply(sender, e)));
741 var evt = e.MatchedEvent;
742 pnlEventDetail.Visible = true;
743 pnlEventDetail.Tag = evt;
744 btnTeleport.Enabled = btnShowOnMap.Enabled = true;
746 txtEventName.Text = evt.Name;
747 txtEventType.Text = evt.Category.ToString();
748 txtEventMaturity.Text = evt.Flags.ToString();
749 txtEventDate.Text = OpenMetaverse.Utils.UnixTimeToDateTime(evt.DateUTC).ToString("r");
750 txtEventDuration.Text = string.Format("{0}:{1:00}", evt.Duration / 60u, evt.Duration % 60u);
751 txtEventOrganizer.Text = instance.Names.Get(evt.Creator, string.Empty);
752 txtEventOrganizer.Tag = evt.Creator;
753 txtEventLocation.Text = string.Format("{0} ({1}, {2}, {3})", evt.SimName, Math.Round(evt.GlobalPos.X % 256), Math.Round(evt.GlobalPos.Y % 256), Math.Round(evt.GlobalPos.Z));
754 txtEventDescription.Text = evt.Desc.Replace("\n", Environment.NewLine);
757 void Names_NameUpdated(object sender, UUIDNameReplyEventArgs e)
761 BeginInvoke(new MethodInvoker(() => Names_NameUpdated(sender, e)));
765 if (!(txtEventOrganizer.Tag is UUID))
770 UUID organizer = (UUID)txtEventOrganizer.Tag;
772 foreach (var name in e.Names)
774 if (name.Key == organizer)
776 txtEventOrganizer.Text = name.Value;
782 private void btnTeleport_Click(object sender, EventArgs e)
784 var evt = (DirectoryManager.EventInfo)pnlEventDetail.Tag;
785 float localX, localY;
786 ulong handle = OpenMetaverse.Helpers.GlobalPosToRegionHandle((float)evt.GlobalPos.X, (float)evt.GlobalPos.Y, out localX, out localY);
787 client.Self.Teleport(handle, new Vector3(localX, localY, (float)evt.GlobalPos.Z));
790 private void btnShowOnMap_Click(object sender, EventArgs e)
792 var evt = (DirectoryManager.EventInfo)pnlEventDetail.Tag;
793 instance.MainForm.ProcessSecondlifeURI(evt.ToSLurl());
796 #endregion Events Search