OSDN Git Service

Added events search
[radegast/radegast.git] / Radegast / GUI / Consoles / SearchConsole.cs
1 // 
2 // Radegast Metaverse Client
3 // Copyright (c) 2009-2013, Radegast Development Team
4 // All rights reserved.
5 // 
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // 
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.
17 // 
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.
28 //
29 // $Id$
30 //
31 using System;
32 using System.Collections.Generic;
33 using System.Windows.Forms;
34 using OpenMetaverse;
35 using System.Diagnostics;
36
37 namespace Radegast
38 {
39     public partial class SearchConsole : UserControl
40     {
41         #region Private members
42         private RadegastInstance instance;
43         private GridClient client { get { return instance.Client; } }
44
45         private FindPeopleConsole console;
46
47         private string lastQuery = string.Empty;
48         private int startResult = 0;
49
50         private int totalResults = 0;
51         #endregion Private members
52
53         #region Construction and disposal
54         public SearchConsole(RadegastInstance instance)
55         {
56             InitializeComponent();
57             Disposed += new EventHandler(SearchConsole_Disposed);
58
59             this.instance = instance;
60
61             comboEventType.SelectedIndex = 0;
62             lvwEvents.Parent.SizeChanged += lvwEvents_SizeChanged;
63             lvwEvents.ListViewItemSorter = new EventSorter();
64
65             // Callbacks
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();
78         }
79
80         void SearchConsole_Disposed(object sender, EventArgs e)
81         {
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;
88         }
89
90         #endregion Construction and disposal
91
92         #region People search
93         private void console_SelectedIndexChanged(object sender, EventArgs e)
94         {
95             btnNewIM.Enabled = btnProfile.Enabled = (console.SelectedName != null);
96         }
97
98
99         void Directory_DirPeopleReply(object sender, DirPeopleReplyEventArgs e)
100         {
101             if (InvokeRequired)
102             {
103                 BeginInvoke(new MethodInvoker(() => Directory_DirPeopleReply(sender, e)));
104                 return;
105             }
106
107             if (console.QueryID != e.QueryID) return;
108
109             totalResults += e.MatchedPeople.Count;
110             lblResultCount.Text = totalResults.ToString() + " people found";
111
112             txtPersonName.Enabled = true;
113             btnFind.Enabled = true;
114
115             btnNext.Enabled = (totalResults > 100);
116             btnPrevious.Enabled = (startResult > 0);
117         }
118
119         private void txtPersonName_TextChanged(object sender, EventArgs e)
120         {
121             btnFind.Enabled = (txtPersonName.Text.Trim().Length > 2);
122         }
123
124         private void btnNewIM_Click(object sender, EventArgs e)
125         {
126             instance.TabConsole.ShowIMTab(console.SelectedAgentUUID, console.SelectedName, true);
127         }
128
129         private void btnFind_Click(object sender, EventArgs e)
130         {
131             lastQuery = txtPersonName.Text;
132             startResult = 0;
133             StartFinding();
134         }
135
136         private void txtPersonName_KeyUp(object sender, KeyEventArgs e)
137         {
138             if (e.KeyCode != Keys.Enter) return;
139             e.SuppressKeyPress = true;
140             if (txtPersonName.Text.Trim().Length < 3) return;
141
142             lastQuery = txtPersonName.Text;
143             startResult = 0;
144             StartFinding();
145         }
146
147         private void StartFinding()
148         {
149             totalResults = 0;
150             lblResultCount.Text = "Searching for " + lastQuery;
151
152             txtPersonName.Enabled = false;
153             btnFind.Enabled = false;
154             btnNewIM.Enabled = false;
155             btnProfile.Enabled = false;
156             btnPrevious.Enabled = false;
157             btnNext.Enabled = false;
158
159             console.ClearResults();
160             console.QueryID = client.Directory.StartPeopleSearch(/*
161                 DirectoryManager.DirFindFlags.NameSort |
162                 DirectoryManager.DirFindFlags.SortAsc |
163                 DirectoryManager.DirFindFlags.People,*/
164                 lastQuery, startResult);
165         }
166
167         private void btnNext_Click(object sender, EventArgs e)
168         {
169             startResult += 100;
170             StartFinding();
171         }
172
173         private void btnPrevious_Click(object sender, EventArgs e)
174         {
175             startResult -= 100;
176             StartFinding();
177         }
178
179         private void btnProfile_Click(object sender, EventArgs e)
180         {
181             instance.MainForm.ShowAgentProfile(console.SelectedName, console.SelectedAgentUUID);
182         }
183
184         private void txtPersonName_KeyDown(object sender, KeyEventArgs e)
185         {
186             if (e.KeyCode == Keys.Enter) e.SuppressKeyPress = true;
187         }
188
189         private void btnLink_Click(object sender, EventArgs e)
190         {
191             ProcessStartInfo sInfo = new ProcessStartInfo(((Button)sender).Tag.ToString());
192             Process.Start(sInfo);
193         }
194         #endregion People search
195
196         #region Places search
197         private UUID placeSearch;
198         private int placeMatches = 0;
199         private int placeStart = 0;
200
201         void Directory_DirPlacesReply(object sender, DirPlacesReplyEventArgs e)
202         {
203             if (e.QueryID != placeSearch) return;
204
205             if (InvokeRequired)
206             {
207                 BeginInvoke(new MethodInvoker(() => Directory_DirPlacesReply(sender, e)));
208                 return;
209             }
210
211             lvwPlaces.BeginUpdate();
212
213             if (e.MatchedParcels.Count == 0)
214                 lvwPlaces.Items.Clear();
215
216             foreach (DirectoryManager.DirectoryParcel parcel in e.MatchedParcels)
217             {
218                 if (parcel.ID == UUID.Zero) continue;
219
220                 ListViewItem item = new ListViewItem();
221                 item.Name = parcel.ID.ToString();
222                 item.Text = parcel.Name;
223                 item.Tag = parcel;
224                 item.SubItems.Add(new ListViewItem.ListViewSubItem(item, parcel.Dwell.ToString()));
225                 lvwPlaces.Items.Add(item);
226             }
227             lvwPlaces.Sort();
228             lvwPlaces.EndUpdate();
229
230             placeMatches += e.MatchedParcels.Count;
231
232             btnNextPlace.Enabled = placeMatches > 100;
233             btnPrevPlace.Enabled = placeStart != 0;
234
235             if (e.MatchedParcels.Count > 0 && e.MatchedParcels[e.MatchedParcels.Count - 1].ID == UUID.Zero)
236                 placeMatches -= 1;
237
238             lblNrPlaces.Visible = true;
239             lblNrPlaces.Text = string.Format("{0} places found", placeMatches > 100 ? "More than " + (placeStart + 100).ToString() : (placeStart + placeMatches).ToString());
240
241
242         }
243
244         private void txtSearchPlace_KeyDown(object sender, KeyEventArgs e)
245         {
246             if (e.KeyCode == Keys.Enter)
247                 e.SuppressKeyPress = true;
248         }
249
250         private void txtSearchPlace_KeyUp(object sender, KeyEventArgs e)
251         {
252             if (e.KeyCode == Keys.Enter)
253             {
254                 e.SuppressKeyPress = true;
255                 if (btnSearchPlace.Enabled)
256                 {
257                     btnSearchPlace_Click(null, EventArgs.Empty);
258                 }
259             }
260         }
261
262         private void txtSearchPlace_TextChanged(object sender, EventArgs e)
263         {
264             if (txtSearchPlace.Text.Length > 0)
265                 btnSearchPlace.Enabled = true;
266             else
267                 btnSearchPlace.Enabled = false;
268         }
269
270         // StartPlacesSearch(DirFindFlags findFlags, ParcelCategory searchCategory, string searchText, string simulatorName, UUID groupID, UUID transactionID)
271         private void btnSearchPlace_Click(object sender, EventArgs e)
272         {
273             placeMatches = 0;
274             placeStart = 0;
275             lvwPlaces.Items.Clear();
276             placeSearch = client.Directory.StartDirPlacesSearch(txtSearchPlace.Text.Trim(), 0);
277         }
278
279         private void btnNextPlace_Click(object sender, EventArgs e)
280         {
281             placeMatches = 0;
282             placeStart += 100;
283             lvwPlaces.Items.Clear();
284             placeSearch = client.Directory.StartDirPlacesSearch(txtSearchPlace.Text.Trim(), placeStart);
285         }
286
287         private void btnPrevPlace_Click(object sender, EventArgs e)
288         {
289             placeMatches = 0;
290             placeStart -= 100;
291             lvwPlaces.Items.Clear();
292             placeSearch = client.Directory.StartDirPlacesSearch(txtSearchPlace.Text.Trim(), placeStart);
293         }
294
295         public class PlaceSorter : System.Collections.IComparer
296         {
297             public enum SortByColumn
298             {
299                 Name,
300                 Traffic
301             }
302
303             public enum SortOrder
304             {
305                 Ascending,
306                 Descending
307             }
308
309             public SortOrder CurrentOrder = SortOrder.Descending;
310             public SortByColumn SortBy = SortByColumn.Traffic;
311
312             public int Compare(object x, object y)
313             {
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;
318
319                 switch (SortBy)
320                 {
321                     case SortByColumn.Name:
322                         if (CurrentOrder == SortOrder.Ascending)
323                             return string.Compare(item1.Text, item2.Text);
324                         else
325                             return string.Compare(item2.Text, item1.Text);
326
327                     case SortByColumn.Traffic:
328                         if (CurrentOrder == SortOrder.Ascending)
329                         {
330                             if (member1.Dwell > member2.Dwell)
331                                 return 1;
332                             else if (member1.Dwell < member2.Dwell)
333                                 return -1;
334                         }
335                         else
336                         {
337                             if (member1.Dwell > member2.Dwell)
338                                 return -1;
339                             else if (member1.Dwell < member2.Dwell)
340                                 return 1;
341                         }
342                         break;
343                 }
344
345                 return 0;
346             }
347         }
348
349         private void lvwPlaces_ColumnClick(object sender, ColumnClickEventArgs e)
350         {
351             PlaceSorter sorter = (PlaceSorter)lvwPlaces.ListViewItemSorter;
352             switch (e.Column)
353             {
354                 case 0:
355                     sorter.SortBy = PlaceSorter.SortByColumn.Name;
356                     break;
357
358                 case 1:
359                     sorter.SortBy = PlaceSorter.SortByColumn.Traffic;
360                     break;
361             }
362
363             if (sorter.CurrentOrder == PlaceSorter.SortOrder.Ascending)
364                 sorter.CurrentOrder = PlaceSorter.SortOrder.Descending;
365             else
366                 sorter.CurrentOrder = PlaceSorter.SortOrder.Ascending;
367
368             lvwPlaces.Sort();
369
370         }
371
372         private void lvwPlaces_SelectedIndexChanged(object sender, EventArgs e)
373         {
374             for (int i = 0; i < pnlPlaceDetail.Controls.Count; i++)
375             {
376                 pnlPlaceDetail.Controls[i].Dispose();
377             }
378             pnlPlaceDetail.Controls.Clear();
379
380             if (lvwPlaces.SelectedItems.Count == 1)
381             {
382                 Landmark l = new Landmark(instance, ((DirectoryManager.DirectoryParcel)lvwPlaces.SelectedItems[0].Tag).ID);
383                 l.Dock = DockStyle.Fill;
384                 pnlPlaceDetail.Controls.Add(l);
385             }
386         }
387         #endregion Places search
388
389         #region Groups search
390         private UUID groupSearch;
391         private int groupMatches = 0;
392         private int groupStart = 0;
393
394         void Directory_DirGroupsReply(object sender, DirGroupsReplyEventArgs e)
395         {
396             if (e.QueryID != groupSearch) return;
397
398             if (InvokeRequired)
399             {
400                 BeginInvoke(new MethodInvoker(() => Directory_DirGroupsReply(sender, e)));
401                 return;
402             }
403
404             lvwGroups.BeginUpdate();
405
406             if (e.MatchedGroups.Count == 0)
407                 lvwGroups.Items.Clear();
408
409             foreach (DirectoryManager.GroupSearchData group in e.MatchedGroups)
410             {
411                 if (group.GroupID == UUID.Zero) continue;
412
413                 ListViewItem item = new ListViewItem();
414                 item.Name = group.GroupID.ToString();
415                 item.Text = group.GroupName;
416                 item.Tag = group;
417                 item.SubItems.Add(new ListViewItem.ListViewSubItem(item, group.Members.ToString()));
418
419                 lvwGroups.Items.Add(item);
420             }
421             lvwGroups.Sort();
422             lvwGroups.EndUpdate();
423
424             groupMatches += e.MatchedGroups.Count;
425             btnNextGroup.Enabled = groupMatches > 100;
426             btnPrevGroup.Enabled = placeStart != 0;
427
428             if (e.MatchedGroups.Count > 0 && e.MatchedGroups[e.MatchedGroups.Count - 1].GroupID == UUID.Zero)
429                 groupMatches -= 1;
430
431             lblNrGroups.Visible = true;
432             lblNrGroups.Text = string.Format("{0} groups found", groupMatches > 100 ? "More than " + (groupStart + 100).ToString() : (groupStart + groupMatches).ToString());
433         }
434
435         private void btnSearchGroup_Click(object sender, EventArgs e)
436         {
437             groupMatches = 0;
438             groupStart = 0;
439             lvwGroups.Items.Clear();
440             groupSearch = client.Directory.StartGroupSearch(txtSearchGroup.Text.Trim(), 0);
441         }
442
443         private void txtSearchGroup_KeyDown(object sender, KeyEventArgs e)
444         {
445             if (e.KeyCode == Keys.Enter)
446             {
447                 e.SuppressKeyPress = e.Handled = true;
448                 btnSearchGroup.PerformClick();
449             }
450         }
451
452         private void txtSearchGroup_TextChanged(object sender, EventArgs e)
453         {
454             if (txtSearchGroup.Text.Length > 1)
455             {
456                 btnSearchGroup.Enabled = true;
457             }
458             else
459             {
460                 btnSearchGroup.Enabled = false;
461             }
462         }
463
464         private void btnPrevGroup_Click(object sender, EventArgs e)
465         {
466             groupMatches = 0;
467             groupStart -= 100;
468             lvwGroups.Items.Clear();
469             groupSearch = client.Directory.StartGroupSearch(txtSearchGroup.Text.Trim(), groupStart);
470         }
471
472         private void btnNextGroup_Click(object sender, EventArgs e)
473         {
474             groupMatches = 0;
475             groupStart += 100;
476             lvwGroups.Items.Clear();
477             groupSearch = client.Directory.StartGroupSearch(txtSearchGroup.Text.Trim(), groupStart);
478         }
479
480         private void lvwGroups_SelectedIndexChanged(object sender, EventArgs e)
481         {
482             foreach (Control c in pnlGroupDetail.Controls)
483             {
484                 c.Dispose();
485             }
486             pnlGroupDetail.Controls.Clear();
487
488             if (lvwGroups.SelectedItems.Count == 1)
489             {
490                 try
491                 {
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);
499                 }
500                 catch { }
501             }
502         }
503
504         private void lvwGroups_ColumnClick(object sender, ColumnClickEventArgs e)
505         {
506             GroupSorter sorter = (GroupSorter)lvwGroups.ListViewItemSorter;
507             switch (e.Column)
508             {
509                 case 0:
510                     sorter.SortBy = GroupSorter.SortByColumn.Name;
511                     break;
512
513                 case 1:
514                     sorter.SortBy = GroupSorter.SortByColumn.Members;
515                     break;
516             }
517
518             if (sorter.CurrentOrder == GroupSorter.SortOrder.Ascending)
519                 sorter.CurrentOrder = GroupSorter.SortOrder.Descending;
520             else
521                 sorter.CurrentOrder = GroupSorter.SortOrder.Ascending;
522
523             lvwGroups.Sort();
524         }
525
526         public class GroupSorter : System.Collections.IComparer
527         {
528             public enum SortByColumn
529             {
530                 Name,
531                 Members
532             }
533
534             public enum SortOrder
535             {
536                 Ascending,
537                 Descending
538             }
539
540             public SortOrder CurrentOrder = SortOrder.Ascending;
541             public SortByColumn SortBy = SortByColumn.Name;
542
543             public int Compare(object x, object y)
544             {
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;
549
550                 switch (SortBy)
551                 {
552                     case SortByColumn.Name:
553                         if (CurrentOrder == SortOrder.Ascending)
554                             return string.Compare(item1.Text, item2.Text);
555                         else
556                             return string.Compare(item2.Text, item1.Text);
557
558                     case SortByColumn.Members:
559                         if (CurrentOrder == SortOrder.Ascending)
560                         {
561                             if (group1.Members > group2.Members)
562                                 return 1;
563                             else if (group1.Members < group2.Members)
564                                 return -1;
565                         }
566                         else
567                         {
568                             if (group1.Members > group2.Members)
569                                 return -1;
570                             else if (group1.Members < group2.Members)
571                                 return 1;
572                         }
573                         break;
574                 }
575
576                 return 0;
577             }
578         }
579         #endregion Groups search
580
581         #region Events Search
582
583         uint eventsPerPage = 200;
584         int eventMatches;
585         uint eventStart;
586         UUID eventSearch;
587
588         DirectoryManager.EventCategories eventType;
589         DirectoryManager.DirFindFlags eventFlags;
590         string eventTime = "u";
591
592         static Dictionary<int, DirectoryManager.EventCategories> eventTypeMap = new Dictionary<int, DirectoryManager.EventCategories>(12);
593
594         void Directory_DirEventsReply(object sender, DirEventsReplyEventArgs e)
595         {
596             if (e.QueryID != eventSearch) return;
597
598             if (InvokeRequired)
599             {
600                 BeginInvoke(new MethodInvoker(() => Directory_DirEventsReply(sender, e)));
601                 return;
602             }
603
604             lvwEvents.BeginUpdate();
605
606             foreach (var evt in e.MatchedEvents)
607             {
608                 if (evt.ID == 0) continue;
609
610                 ListViewItem item = new ListViewItem();
611                 item.Name = "evt" + evt.ID.ToString();
612                 item.Text = evt.Name;
613                 item.Tag = evt;
614                 item.SubItems.Add(new ListViewItem.ListViewSubItem(item, evt.Date));
615
616                 lvwEvents.Items.Add(item);
617             }
618
619             lvwEvents.Sort();
620             lvwEvents.EndUpdate();
621
622             eventMatches += e.MatchedEvents.Count;
623             btnNextEvent.Enabled = eventMatches > eventsPerPage;
624             btnPrevEvent.Enabled = eventStart != 0;
625
626             if (e.MatchedEvents.Count > 0 && e.MatchedEvents[e.MatchedEvents.Count - 1].ID == 0)
627                 eventMatches -= 1;
628
629             lblNrEvents.Visible = true;
630             lblNrEvents.Text = string.Format("{0} events found", eventMatches > eventsPerPage ? "More than " + (eventStart + eventsPerPage).ToString() : (eventStart + eventMatches).ToString());
631         }
632
633
634         private void btnSearchEvents_Click(object sender, EventArgs e)
635         {
636             if (eventTypeMap.Count == 0)
637             {
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;
649             }
650
651             eventType = DirectoryManager.EventCategories.All;
652
653             if (eventTypeMap.ContainsKey(comboEventType.SelectedIndex))
654             {
655                 eventType = eventTypeMap[comboEventType.SelectedIndex];
656             }
657
658
659             eventFlags = DirectoryManager.DirFindFlags.DateEvents |
660                 DirectoryManager.DirFindFlags.IncludePG |
661                 DirectoryManager.DirFindFlags.IncludeMature |
662                 DirectoryManager.DirFindFlags.IncludeAdult;
663
664             eventMatches = 0;
665             eventStart = 0;
666             PerformEventSearch();
667         }
668
669         void PerformEventSearch()
670         {
671             lvwEvents_SizeChanged(this, EventArgs.Empty);
672             lvwEvents.Items.Clear();
673             eventSearch = client.Directory.StartEventsSearch(txtSearchEvents.Text.Trim(), eventFlags, eventTime, eventStart, eventType);
674         }
675
676         private void btnSearchEvents_KeyDown(object sender, KeyEventArgs e)
677         {
678             if (e.KeyCode == Keys.Enter)
679             {
680                 e.SuppressKeyPress = e.Handled = true;
681                 btnSearchEvents.PerformClick();
682             }
683         }
684
685         private void btnPrevEvent_Click(object sender, EventArgs e)
686         {
687             eventMatches = 0;
688             eventStart -= eventsPerPage;
689             PerformEventSearch();
690         }
691
692         private void btnNextEvent_Click(object sender, EventArgs e)
693         {
694             eventMatches = 0;
695             eventStart += eventsPerPage;
696             PerformEventSearch();
697         }
698
699         void lvwEvents_SizeChanged(object sender, EventArgs e)
700         {
701             lvwEvents.Columns[0].Width = lvwEvents.Width - 130;
702         }
703
704         class EventSorter : System.Collections.IComparer
705         {
706             public int Compare(object a, object b)
707             {
708                 try
709                 {
710                     DirectoryManager.EventsSearchData e1 = (DirectoryManager.EventsSearchData)((ListViewItem)a).Tag;
711                     DirectoryManager.EventsSearchData e2 = (DirectoryManager.EventsSearchData)((ListViewItem)b).Tag;
712
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);
716                 }
717                 catch { }
718                 return 0;
719             }
720         }
721
722         private void lvwEvents_SelectedIndexChanged(object sender, EventArgs e)
723         {
724             pnlEventDetail.Visible = false;
725
726             if (lvwEvents.SelectedItems.Count == 1 && (lvwEvents.SelectedItems[0].Tag is DirectoryManager.EventsSearchData))
727             {
728                 var evt = (DirectoryManager.EventsSearchData)lvwEvents.SelectedItems[0].Tag;
729                 client.Directory.EventInfoRequest(evt.ID);
730             }
731         }
732
733         void Directory_EventInfoReply(object sender, EventInfoReplyEventArgs e)
734         {
735             if (InvokeRequired)
736             {
737                 BeginInvoke(new MethodInvoker(() => Directory_EventInfoReply(sender, e)));
738                 return;
739             }
740
741             var evt = e.MatchedEvent;
742             pnlEventDetail.Visible = true;
743             pnlEventDetail.Tag = evt;
744             btnTeleport.Enabled = btnShowOnMap.Enabled = true;
745
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);
755         }
756
757         void Names_NameUpdated(object sender, UUIDNameReplyEventArgs e)
758         {
759             if (InvokeRequired)
760             {
761                 BeginInvoke(new MethodInvoker(() => Names_NameUpdated(sender, e)));
762                 return;
763             }
764
765             if (!(txtEventOrganizer.Tag is UUID))
766             {
767                 return;
768             }
769
770             UUID organizer = (UUID)txtEventOrganizer.Tag;
771
772             foreach (var name in e.Names)
773             {
774                 if (name.Key == organizer)
775                 {
776                     txtEventOrganizer.Text = name.Value;
777                     break;
778                 }
779             }
780         }
781
782         private void btnTeleport_Click(object sender, EventArgs e)
783         {
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));
788         }
789
790         private void btnShowOnMap_Click(object sender, EventArgs e)
791         {
792             var evt = (DirectoryManager.EventInfo)pnlEventDetail.Tag;
793             instance.MainForm.ProcessSecondlifeURI(evt.ToSLurl());
794         }
795
796         #endregion Events Search
797     }
798 }