1 ' Tween - Client of Twitter
2 ' Copyright (c) 2007-2009 kiri_feather (@kiri_feather) <kiri_feather@gmail.com>
3 ' (c) 2008-2009 Moz (@syo68k) <http://iddy.jp/profile/moz/>
4 ' (c) 2008-2009 takeshik (@takeshik) <http://www.takeshik.org/>
7 ' This file is part of Tween.
9 ' This program is free software; you can redistribute it and/or modify it
10 ' under the terms of the GNU General Public License as published by the Free
11 ' Software Foundation; either version 3 of the License, or (at your option)
14 ' This program is distributed in the hope that it will be useful, but
15 ' WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ' or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 ' You should have received a copy of the GNU General Public License along
20 ' with this program. If not, see <http://www.gnu.org/licenses/>, or write to
21 ' the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
22 ' Boston, MA 02110-1301, USA.
24 Imports System.Collections.Generic
25 Imports System.Collections.ObjectModel
26 Imports Tween.TweenCustomControl
27 Imports System.Text.RegularExpressions
30 Public NotInheritable Class PostClass
31 Private _Nick As String
32 Private _Data As String
33 Private _ImageUrl As String
34 Private _Name As String
35 Private _PDate As Date
37 Private _IsFav As Boolean
38 Private _OrgData As String
39 Private _IsRead As Boolean
40 Private _IsReply As Boolean
41 Private _IsProtect As Boolean
42 Private _IsOWL As Boolean
43 Private _IsMark As Boolean
44 Private _InReplyToUser As String
45 Private _InReplyToId As Long
46 Private _Source As String
47 Private _ReplyToList As New List(Of String)
48 Private _IsMe As Boolean
49 Private _ImageIndex As Integer
50 Private _IsDm As Boolean
51 Private _statuses As Statuses = Statuses.None
53 Private _FilterHit As Boolean
54 Private _RetweetedBy As String
65 Public Sub New(ByVal Nickname As String, _
66 ByVal Data As String, _
67 ByVal OriginalData As String, _
68 ByVal ImageUrl As String, _
69 ByVal Name As String, _
70 ByVal PDate As Date, _
72 ByVal IsFav As Boolean, _
73 ByVal IsRead As Boolean, _
74 ByVal IsReply As Boolean, _
75 ByVal IsProtect As Boolean, _
76 ByVal IsOwl As Boolean, _
77 ByVal IsMark As Boolean, _
78 ByVal InReplyToUser As String, _
79 ByVal InReplyToId As Long, _
80 ByVal Source As String, _
81 ByVal ReplyToList As List(Of String), _
82 ByVal IsMe As Boolean, _
83 ByVal ImageIndex As Integer, _
84 ByVal IsDm As Boolean, _
86 ByVal FilterHit As Boolean, _
87 ByVal RetweetedBy As String)
95 _OrgData = OriginalData
98 _IsProtect = IsProtect
101 _InReplyToUser = InReplyToUser
102 _InReplyToId = InReplyToId
104 _ReplyToList = ReplyToList
106 _ImageIndex = ImageIndex
109 _FilterHit = FilterHit
110 _RetweetedBy = RetweetedBy
116 Public Property Nickname() As String
120 Set(ByVal value As String)
124 Public Property Data() As String
128 Set(ByVal value As String)
132 Public Property ImageUrl() As String
136 Set(ByVal value As String)
140 Public Property Name() As String
144 Set(ByVal value As String)
148 Public Property PDate() As Date
152 Set(ByVal value As Date)
156 Public Property Id() As Long
160 Set(ByVal value As Long)
164 Public Property IsFav() As Boolean
168 Set(ByVal value As Boolean)
172 Public Property OriginalData() As String
176 Set(ByVal value As String)
180 Public Property IsRead() As Boolean
184 Set(ByVal value As Boolean)
186 _statuses = _statuses Or Statuses.Read
188 _statuses = _statuses And Not Statuses.Read
193 Public Property IsReply() As Boolean
197 Set(ByVal value As Boolean)
201 Public Property IsProtect() As Boolean
205 Set(ByVal value As Boolean)
207 _statuses = _statuses Or Statuses.Protect
209 _statuses = _statuses And Not Statuses.Protect
214 Public Property IsOwl() As Boolean
218 Set(ByVal value As Boolean)
222 Public Property IsMark() As Boolean
226 Set(ByVal value As Boolean)
228 _statuses = _statuses Or Statuses.Mark
230 _statuses = _statuses And Not Statuses.Mark
235 Public Property InReplyToUser() As String
237 Return _InReplyToUser
239 Set(ByVal value As String)
240 _InReplyToUser = value
243 Public Property InReplyToId() As Long
247 Set(ByVal value As Long)
251 Public Property Source() As String
255 Set(ByVal value As String)
259 Public Property ReplyToList() As List(Of String)
263 Set(ByVal value As List(Of String))
267 Public Property IsMe() As Boolean
271 Set(ByVal value As Boolean)
275 Public Property ImageIndex() As Integer
279 Set(ByVal value As Integer)
283 Public Property IsDm() As Boolean
287 Set(ByVal value As Boolean)
291 Public ReadOnly Property StatusIndex() As Integer
296 Public Property Uid() As Long
300 Set(ByVal value As Long)
304 Public Property FilterHit() As Boolean
308 Set(ByVal value As Boolean)
312 Public Property RetweetedBy() As String
316 Set(ByVal value As String)
322 Public NotInheritable Class TabInformations
323 '個別タブの情報をDictionaryで保持
324 Private _sorter As IdComparerClass
325 Private _tabs As New Dictionary(Of String, TabClass)
326 Private _statuses As Dictionary(Of Long, PostClass) = New Dictionary(Of Long, PostClass)
327 Private _addedIds As List(Of Long)
330 'AddPost(複数回) -> DistributePosts -> SubmitUpdate
333 Private _addCount As Integer
334 Private _soundFile As String
335 Private _notifyPosts As List(Of PostClass)
336 Private ReadOnly LockObj As New Object
337 Private ReadOnly LockUnread As New Object
339 Private Shared _instance As TabInformations = New TabInformations
342 _sorter = New IdComparerClass(Me)
345 Public Shared Function GetInstance() As TabInformations
346 Return _instance 'singleton
349 Public Sub AddTab(ByVal TabName As String, ByVal TabType As TabUsageType)
350 _tabs.Add(TabName, New TabClass(TabName, TabType))
353 Public Sub AddTab(ByVal TabName As String, ByVal Tab As TabClass)
354 _tabs.Add(TabName, Tab)
357 Public Sub RemoveTab(ByVal TabName As String)
359 If IsDefaultTab(TabName) Then Exit Sub '念のため
360 Dim homeTab As TabClass = GetTabByType(TabUsageType.Home)
361 Dim dmName As String = GetTabByType(TabUsageType.DirectMessage).TabName
363 For idx As Integer = 0 To _tabs(TabName).AllCount - 1
364 Dim exist As Boolean = False
365 Dim Id As Long = _tabs(TabName).GetId(idx)
366 For Each key As String In _tabs.Keys
367 If Not key = TabName AndAlso key <> dmName Then
368 If _tabs(key).Contains(Id) Then
374 If Not exist Then homeTab.Add(Id, _statuses(Id).IsRead, False)
377 _tabs.Remove(TabName)
381 Public Function ContainsTab(ByVal TabText As String) As Boolean
382 Return _tabs.ContainsKey(TabText)
385 Public Function ContainsTab(ByVal ts As TabClass) As Boolean
386 Return _tabs.ContainsValue(ts)
389 Public Property Tabs() As Dictionary(Of String, TabClass)
393 Set(ByVal value As Dictionary(Of String, TabClass))
398 Public ReadOnly Property KeysTab() As Collections.Generic.Dictionary(Of String, TabClass).KeyCollection
404 Public Sub SortPosts()
405 For Each key As String In _tabs.Keys
406 _tabs(key).Sort(_sorter)
410 Public ReadOnly Property Sorter() As IdComparerClass
416 Public Property SortOrder() As SortOrder
420 Set(ByVal value As SortOrder)
421 _sorter.Order = value
425 Public Property SortMode() As IdComparerClass.ComparerMode
429 Set(ByVal value As IdComparerClass.ComparerMode)
434 Public Sub ToggleSortOrder(ByVal SortMode As IdComparerClass.ComparerMode)
435 If _sorter.Mode = SortMode Then
436 If _sorter.Order = Windows.Forms.SortOrder.Ascending Then
437 _sorter.Order = Windows.Forms.SortOrder.Descending
439 _sorter.Order = Windows.Forms.SortOrder.Ascending
442 _sorter.Mode = SortMode
443 _sorter.Order = Windows.Forms.SortOrder.Ascending
448 Public Sub RemovePost(ByVal Name As String, ByVal Id As Long)
450 Dim post As PostClass = _statuses(Id)
452 Dim tab As TabClass = _tabs(Name)
453 If tab.Contains(Id) Then
454 If tab.UnreadManage AndAlso Not post.IsRead Then '未読管理
457 Me.SetNextUnreadId(Id, tab)
465 Public Sub RemovePost(ByVal Id As Long)
467 Dim post As PostClass = _statuses(Id)
469 For Each key As String In _tabs.Keys
470 Dim tab As TabClass = _tabs(key)
471 If tab.Contains(Id) Then
472 If tab.UnreadManage AndAlso Not post.IsRead Then '未読管理
475 Me.SetNextUnreadId(Id, tab)
485 Public Function GetOldestUnreadId(ByVal TabName As String) As Integer
486 Dim tb As TabClass = _tabs(TabName)
487 If tb.OldestUnreadId > -1 AndAlso _
488 tb.Contains(tb.OldestUnreadId) AndAlso _
489 tb.UnreadCount > 0 Then
491 If _statuses.Item(tb.OldestUnreadId).IsRead Then
494 Me.SetNextUnreadId(-1, tb) '頭から探索
496 If tb.OldestUnreadId = -1 Then
499 Return tb.IndexOf(tb.OldestUnreadId)
502 Return tb.IndexOf(tb.OldestUnreadId) '最短経路
505 '一見未読なさそうだが、未読カウントはあるので探索
506 If tb.UnreadCount > 0 Then
508 Me.SetNextUnreadId(-1, tb)
510 If tb.OldestUnreadId = -1 Then
513 Return tb.IndexOf(tb.OldestUnreadId)
521 Private Sub SetNextUnreadId(ByVal CurrentId As Long, ByVal Tab As TabClass)
522 'CurrentID:今既読にしたID(OldestIDの可能性あり)
523 '最古未読が設定されていて、既読の場合(1発言以上存在)
524 If Tab.OldestUnreadId > -1 AndAlso _
525 _statuses.ContainsKey(Tab.OldestUnreadId) AndAlso _
526 _statuses.Item(Tab.OldestUnreadId).IsRead AndAlso _
527 _sorter.Mode = IdComparerClass.ComparerMode.Id Then '次の未読探索
528 If Tab.UnreadCount = 0 Then
530 Tab.OldestUnreadId = -1
531 ElseIf Tab.OldestUnreadId = CurrentId Then
532 '最古IDを既読にしたタイミング→次のIDから続けて探索
533 Dim idx As Integer = Tab.IndexOf(CurrentId)
536 FindUnreadId(idx, Tab)
539 FindUnreadId(-1, Tab)
543 FindUnreadId(-1, Tab)
547 FindUnreadId(-1, Tab)
551 Private Sub FindUnreadId(ByVal StartIdx As Integer, ByVal Tab As TabClass)
552 If Tab.AllCount = 0 Then
553 Tab.OldestUnreadId = -1
557 Dim toIdx As Integer = 0
558 Dim stp As Integer = 1
559 Tab.OldestUnreadId = -1
560 If _sorter.Order = Windows.Forms.SortOrder.Ascending Then
561 If StartIdx = -1 Then
565 If StartIdx > Tab.AllCount - 1 Then StartIdx = Tab.AllCount - 1 '念のため
567 toIdx = Tab.AllCount - 1
568 If toIdx < 0 Then toIdx = 0 '念のため
571 If StartIdx = -1 Then
572 StartIdx = Tab.AllCount - 1
576 If StartIdx < 0 Then StartIdx = 0 '念のため
580 For i As Integer = StartIdx To toIdx Step stp
581 If Not _statuses(Tab.GetId(i)).IsRead Then
582 Tab.OldestUnreadId = Tab.GetId(i)
588 Public Function DistributePosts() As Integer
591 If _addedIds Is Nothing Then Return 0
592 If _addedIds.Count = 0 Then Return 0
594 If _notifyPosts Is Nothing Then _notifyPosts = New List(Of PostClass)
595 Me.Distribute() 'タブに仮振分
596 _addCount = _addedIds.Count
598 _addedIds = Nothing '後始末
603 Public Function SubmitUpdate(ByRef soundFile As String, ByRef notifyPosts As PostClass()) As Integer
606 If _notifyPosts Is Nothing Then
608 notifyPosts = Nothing
612 For Each key As String In _tabs.Keys
613 _tabs(key).AddSubmit() '振分確定(各タブに反映)
617 soundFile = _soundFile
619 notifyPosts = _notifyPosts.ToArray()
621 _notifyPosts = Nothing
622 Dim retCnt As Integer = _addCount
624 Return retCnt '件数(EndUpdateの戻り値と同じ)
628 Private Sub Distribute()
629 '各タブのフィルターと照合。合致したらタブにID追加
630 '通知メッセージ用に、表示必要な発言リストと再生サウンドを返す
631 'notifyPosts = New List(Of PostClass)
632 Dim homeTab As TabClass = GetTabByType(TabUsageType.Home)
633 Dim replyTab As TabClass = GetTabByType(TabUsageType.Mentions)
634 Dim dmTab As TabClass = GetTabByType(TabUsageType.DirectMessage)
635 Dim favTab As TabClass = GetTabByType(TabUsageType.Favorites)
636 For Each id As Long In _addedIds
637 Dim post As PostClass = _statuses(id)
638 If Not post.IsDm Then
639 Dim add As Boolean = False '通知リスト追加フラグ
640 Dim mv As Boolean = False '移動フラグ(Recent追加有無)
641 For Each tn As String In _tabs.Keys
642 Dim rslt As HITRESULT = _tabs(tn).AddFiltered(post.Id, post.IsRead, post.Name, post.Data, post.OriginalData)
643 If rslt <> HITRESULT.None Then
644 If rslt = HITRESULT.CopyAndMark Then post.IsMark = True 'マークあり
645 If rslt = HITRESULT.Move Then
649 If _tabs(tn).Notify Then add = True '通知あり
650 If Not _tabs(tn).SoundFile = "" AndAlso _soundFile = "" Then
651 _soundFile = _tabs(tn).SoundFile 'wavファイル(未設定の場合のみ)
653 post.FilterHit = True
655 post.FilterHit = False
658 If Not mv Then '移動されなかったらRecentに追加
659 homeTab.Add(post.Id, post.IsRead, True)
660 If Not homeTab.SoundFile = "" AndAlso _soundFile = "" Then _soundFile = homeTab.SoundFile
661 If homeTab.Notify Then add = True
663 If post.IsReply Then 'ReplyだったらReplyタブに追加
664 replyTab.Add(post.Id, post.IsRead, True)
665 If Not replyTab.SoundFile = "" Then _soundFile = replyTab.SoundFile
666 If replyTab.Notify Then add = True
668 If post.IsFav Then 'Fav済み発言だったらFavoritesタブに追加
669 If favTab.Contains(post.Id) Then
674 favTab.Add(post.Id, post.IsRead, True)
675 If Not favTab.SoundFile = "" Then _soundFile = favTab.SoundFile
676 If favTab.Notify Then add = True
679 If add Then _notifyPosts.Add(post)
681 dmTab.Add(post.Id, post.IsRead, True)
682 If dmTab.Notify Then _notifyPosts.Add(post)
683 _soundFile = dmTab.SoundFile
688 Public Sub AddPost(ByVal Item As PostClass)
690 If _statuses.ContainsKey(Item.Id) Then
692 _statuses.Item(Item.Id).IsFav = True
694 Exit Sub '追加済みなら何もしない
697 _statuses.Add(Item.Id, Item) 'DMと区別しない?
699 If _addedIds Is Nothing Then _addedIds = New List(Of Long) 'タブ追加用IDコレクション準備
700 _addedIds.Add(Item.Id)
704 Public Sub SetRead(ByVal Read As Boolean, ByVal TabName As String, ByVal Index As Integer)
705 'Read:True=既読へ False=未読へ
706 Dim tb As TabClass = _tabs(TabName)
708 If tb.UnreadManage = False Then Exit Sub '未読管理していなければ終了
710 Dim Id As Long = tb.GetId(Index)
712 If _statuses(Id).IsRead = Read Then Exit Sub '状態変更なければ終了
714 _statuses(Id).IsRead = Read '指定の状態に変更
719 Me.SetNextUnreadId(Id, tb) '次の未読セット
720 '他タブの最古未読IDはタブ切り替え時に。
721 For Each key As String In _tabs.Keys
722 If key <> TabName AndAlso _
723 _tabs(key).UnreadManage AndAlso _
724 _tabs(key).Contains(Id) Then
725 _tabs(key).UnreadCount -= 1
726 If _tabs(key).OldestUnreadId = Id Then _tabs(key).OldestUnreadId = -1
731 If tb.OldestUnreadId > Id OrElse tb.OldestUnreadId = -1 Then tb.OldestUnreadId = Id
732 For Each key As String In _tabs.Keys
733 If Not key = TabName AndAlso _tabs(key).UnreadManage AndAlso _tabs(key).Contains(Id) Then
734 _tabs(key).UnreadCount += 1
735 If _tabs(key).OldestUnreadId > Id Then _tabs(key).OldestUnreadId = Id
743 Dim tb As TabClass = GetTabByType(TabUsageType.Home)
744 If tb.UnreadManage = False Then Exit Sub
746 For i As Integer = 0 To tb.AllCount - 1
747 Dim id As Long = tb.GetId(i)
748 If Not _statuses(id).IsDm AndAlso _
749 Not _statuses(id).IsReply AndAlso _
750 Not _statuses(id).IsRead AndAlso _
751 Not _statuses(id).FilterHit Then
752 _statuses(id).IsRead = True
753 Me.SetNextUnreadId(id, tb) '次の未読セット
754 For Each key As String In _tabs.Keys
755 If _tabs(key).UnreadManage AndAlso _
756 _tabs(key).Contains(id) Then
757 _tabs(key).UnreadCount -= 1
758 If _tabs(key).OldestUnreadId = id Then _tabs(key).OldestUnreadId = -1
765 Public ReadOnly Property Item(ByVal ID As Long) As PostClass
771 Public ReadOnly Property Item(ByVal TabName As String, ByVal Index As Integer) As PostClass
773 Return _statuses(_tabs(TabName).GetId(Index))
777 Public ReadOnly Property Item(ByVal TabName As String, ByVal StartIndex As Integer, ByVal EndIndex As Integer) As PostClass()
779 Dim length As Integer = EndIndex - StartIndex + 1
780 Dim posts() As PostClass = New PostClass(length - 1) {}
781 For i As Integer = 0 To length - 1
782 posts(i) = _statuses(_tabs(TabName).GetId(StartIndex + i))
788 Public ReadOnly Property ItemCount() As Integer
791 Return _statuses.Count
796 Public Function ContainsKey(ByVal Id As Long) As Boolean
798 Return _statuses.ContainsKey(Id)
802 Public Sub SetUnreadManage(ByVal Manage As Boolean)
804 For Each key As String In _tabs.Keys
805 Dim tb As TabClass = _tabs(key)
806 If tb.UnreadManage Then
808 Dim cnt As Integer = 0
809 Dim oldest As Long = Long.MaxValue
810 For Each id As Long In tb.BackupIds
811 If Not _statuses(id).IsRead Then
813 If oldest > id Then oldest = id
816 tb.OldestUnreadId = oldest
822 For Each key As String In _tabs.Keys
823 Dim tb As TabClass = _tabs(key)
824 If tb.UnreadManage AndAlso tb.UnreadCount > 0 Then
827 tb.OldestUnreadId = -1
834 Public Sub RenameTab(ByVal Original As String, ByVal NewName As String)
835 Dim tb As TabClass = _tabs(Original)
836 _tabs.Remove(Original)
838 _tabs.Add(NewName, tb)
841 Public Sub FilterAll()
843 Dim tbr As TabClass = GetTabByType(TabUsageType.Home)
844 Dim replyTab As TabClass = GetTabByType(TabUsageType.Mentions)
845 For Each key As String In _tabs.Keys
846 Dim tb As TabClass = _tabs(key)
847 If tb.FilterModified Then
848 tb.FilterModified = False
849 Dim orgIds() As Long = tb.BackupIds()
851 ''''''''''''''フィルター前のIDsを退避。どのタブにも含まれないidはrecentへ追加
852 ''''''''''''''moveフィルターにヒットした際、recentに該当あればrecentから削除
853 For Each id As Long In _statuses.Keys
854 Dim post As PostClass = _statuses.Item(id)
855 If post.IsDm Then Continue For
856 Dim rslt As HITRESULT = tb.AddFiltered(post.Id, post.IsRead, post.Name, post.Data, post.OriginalData)
858 Case HITRESULT.CopyAndMark
859 post.IsMark = True 'マークあり
860 post.FilterHit = True
862 tbr.Remove(post.Id, post.IsRead)
864 post.FilterHit = True
867 post.FilterHit = True
869 If key = replyTab.TabName AndAlso post.IsReply Then replyTab.Add(post.Id, post.IsRead, True)
870 If post.IsFav Then GetTabByType(TabUsageType.Favorites).Add(post.Id, post.IsRead, True)
871 post.FilterHit = False
875 For Each id As Long In orgIds
876 Dim hit As Boolean = False
877 For Each tkey As String In _tabs.Keys
878 If _tabs(tkey).Contains(id) Then
883 If Not hit Then tbr.Add(id, _statuses(id).IsRead, False)
892 Public Function GetId(ByVal TabName As String, ByVal IndexCollection As ListView.SelectedIndexCollection) As Long()
893 If IndexCollection.Count = 0 Then Return Nothing
895 Dim tb As TabClass = _tabs(TabName)
896 Dim Ids(IndexCollection.Count - 1) As Long
897 For i As Integer = 0 To Ids.Length - 1
898 Ids(i) = tb.GetId(IndexCollection(i))
903 Public Function GetId(ByVal TabName As String, ByVal Index As Integer) As Long
904 Return _tabs(TabName).GetId(Index)
907 Public Function IndexOf(ByVal TabName As String, ByVal Ids() As Long) As Integer()
908 If Ids Is Nothing Then Return Nothing
909 Dim idx(Ids.Length - 1) As Integer
910 Dim tb As TabClass = _tabs(TabName)
911 For i As Integer = 0 To Ids.Length - 1
912 idx(i) = tb.IndexOf(Ids(i))
917 Public Function IndexOf(ByVal TabName As String, ByVal Id As Long) As Integer
918 Return _tabs(TabName).IndexOf(Id)
921 Public Sub ClearTabIds(ByVal TabName As String)
923 For Each Id As Long In _tabs(TabName).BackupIds
924 Dim Hit As Boolean = False
925 For Each tb As TabClass In _tabs.Values
926 If tb.Contains(Id) Then
931 If Not Hit Then _statuses.Remove(Id)
934 _tabs(TabName).ClearIDs()
937 Public Sub SetTabUnreadManage(ByVal TabName As String, ByVal Manage As Boolean)
938 Dim tb As TabClass = _tabs(TabName)
941 Dim cnt As Integer = 0
942 Dim oldest As Long = Long.MaxValue
943 For Each id As Long In tb.BackupIds
944 If Not _statuses(id).IsRead Then
946 If oldest > id Then oldest = id
949 tb.OldestUnreadId = oldest
952 tb.OldestUnreadId = -1
956 tb.UnreadManage = Manage
959 Public Sub RefreshOwl(ByVal follower As List(Of String))
961 For Each id As Long In _statuses.Keys
962 If Not _statuses(id).IsDm Then _statuses(id).IsOwl = Not follower.Contains(_statuses(id).Name.ToLower())
967 Public Function GetTabByType(ByVal tabType As TabUsageType) As TabClass
968 'Home,Mentions,DM,Favは1つに制限する
969 'その他のタイプを指定されたら、最初に合致したものを返す
971 For Each tb As TabClass In _tabs.Values
972 If tb.TabType = tabType Then Return tb
978 Public Function IsDefaultTab(ByVal tabName As String) As Boolean
979 If tabName IsNot Nothing AndAlso _
980 _tabs.ContainsKey(tabName) AndAlso _
981 (_tabs(tabName).TabType = TabUsageType.Home OrElse _
982 _tabs(tabName).TabType = TabUsageType.Mentions OrElse _
983 _tabs(tabName).TabType = TabUsageType.DirectMessage OrElse _
984 _tabs(tabName).TabType = TabUsageType.Favorites) Then
993 Public NotInheritable Class TabClass
994 Private _unreadManage As Boolean = False
995 Private _notify As Boolean = False
996 Private _soundFile As String = ""
997 Private _filters As List(Of FiltersClass)
998 Private _oldestUnreadItem As Long = -1 'ID
999 Private _unreadCount As Integer = 0
1000 Private _ids As List(Of Long)
1001 Private _filterMod As Boolean = False
1002 Private _tmpIds As List(Of TempolaryId)
1003 Private _tabName As String = ""
1004 Private _tabType As TabUsageType = TabUsageType.Undefined
1005 'Private rwLock As New System.Threading.ReaderWriterLock() 'フィルタ用
1007 Private Structure TempolaryId
1009 Public Read As Boolean
1011 Public Sub New(ByVal argId As Long, ByVal argRead As Boolean)
1018 _filters = New List(Of FiltersClass)
1021 _unreadManage = True
1022 _ids = New List(Of Long)
1023 _oldestUnreadItem = -1
1024 _tabType = TabUsageType.Undefined
1027 Public Sub New(ByVal TabName As String, ByVal TabType As TabUsageType)
1028 Me.TabName = TabName
1029 _filters = New List(Of FiltersClass)
1032 _unreadManage = True
1033 _ids = New List(Of Long)
1034 _oldestUnreadItem = -1
1038 Public Sub Sort(ByVal Sorter As IdComparerClass)
1039 _ids.Sort(Sorter.CmpMethod)
1043 Private Sub Add(ByVal ID As Long, ByVal Read As Boolean)
1044 If Me._ids.Contains(ID) Then Exit Sub
1048 If Not Read AndAlso Me._unreadManage Then
1049 Me._unreadCount += 1
1050 If Me._oldestUnreadItem = -1 Then
1051 Me._oldestUnreadItem = ID
1053 If ID < Me._oldestUnreadItem Then Me._oldestUnreadItem = ID
1058 Public Sub Add(ByVal ID As Long, ByVal Read As Boolean, ByVal Temporary As Boolean)
1059 If Not Temporary Then
1062 If _tmpIds Is Nothing Then _tmpIds = New List(Of TempolaryId)
1063 _tmpIds.Add(New TempolaryId(ID, Read))
1068 Public Function AddFiltered(ByVal ID As Long, _
1069 ByVal Read As Boolean, _
1070 ByVal Name As String, _
1071 ByVal Body As String, _
1072 ByVal OrgData As String) As HITRESULT
1074 ' rwLock.AcquireReaderLock(System.Threading.Timeout.Infinite) '読み取りロック取得
1076 Dim rslt As HITRESULT = HITRESULT.None
1078 For Each ft As FiltersClass In _filters
1079 Select Case ft.IsHit(Name, Body, OrgData) 'フィルタクラスでヒット判定
1082 If rslt <> HITRESULT.CopyAndMark Then rslt = HITRESULT.Copy
1083 Case HITRESULT.CopyAndMark
1084 rslt = HITRESULT.CopyAndMark
1086 rslt = HITRESULT.Move
1087 Case HITRESULT.Exclude
1088 rslt = HITRESULT.None
1093 If rslt <> HITRESULT.None Then
1094 If _tmpIds Is Nothing Then _tmpIds = New List(Of TempolaryId)
1095 _tmpIds.Add(New TempolaryId(ID, Read))
1099 Return rslt 'マーク付けは呼び出し元で行うこと
1102 ' rwLock.ReleaseReaderLock()
1106 Public Sub AddSubmit()
1107 If _tmpIds Is Nothing Then Exit Sub
1108 For Each tId As TempolaryId In _tmpIds
1109 Me.Add(tId.Id, tId.Read)
1115 Public Sub Remove(ByVal Id As Long)
1116 If Not Me._ids.Contains(Id) Then Exit Sub
1121 Public Sub Remove(ByVal Id As Long, ByVal Read As Boolean)
1122 If Not Me._ids.Contains(Id) Then Exit Sub
1124 If Not Read AndAlso Me._unreadManage Then
1125 Me._unreadCount -= 1
1126 Me._oldestUnreadItem = -1
1132 Public Property UnreadManage() As Boolean
1134 Return _unreadManage
1136 Set(ByVal value As Boolean)
1137 Me._unreadManage = value
1139 Me._oldestUnreadItem = -1
1145 Public Property Notify() As Boolean
1149 Set(ByVal value As Boolean)
1154 Public Property SoundFile() As String
1158 Set(ByVal value As String)
1163 <Xml.Serialization.XmlIgnore()> _
1164 Public Property OldestUnreadId() As Long
1166 Return _oldestUnreadItem
1168 Set(ByVal value As Long)
1169 _oldestUnreadItem = value
1173 <Xml.Serialization.XmlIgnore()> _
1174 Public Property UnreadCount() As Integer
1178 Set(ByVal value As Integer)
1179 _unreadCount = value
1183 Public ReadOnly Property AllCount() As Integer
1185 Return Me._ids.Count
1189 Public Function GetFilters() As FiltersClass()
1190 Return _filters.ToArray()
1193 Public Sub RemoveFilter(ByVal filter As FiltersClass)
1194 _filters.Remove(filter)
1198 Public Function AddFilter(ByVal filter As FiltersClass) As Boolean
1199 If _filters.Contains(filter) Then Return False
1200 _filters.Add(filter)
1205 Public Sub EditFilter(ByVal original As FiltersClass, ByVal modified As FiltersClass)
1206 original.BodyFilter = modified.BodyFilter
1207 original.NameFilter = modified.NameFilter
1208 original.SearchBoth = modified.SearchBoth
1209 original.SearchUrl = modified.SearchUrl
1210 original.UseRegex = modified.UseRegex
1211 original.CaseSensitive = modified.CaseSensitive
1212 original.ExBodyFilter = modified.ExBodyFilter
1213 original.ExNameFilter = modified.ExNameFilter
1214 original.ExSearchBoth = modified.ExSearchBoth
1215 original.ExSearchUrl = modified.ExSearchUrl
1216 original.ExUseRegex = modified.ExUseRegex
1217 original.ExCaseSensitive = modified.ExCaseSensitive
1218 original.MoveFrom = modified.MoveFrom
1219 original.SetMark = modified.SetMark
1223 <Xml.Serialization.XmlIgnore()> _
1224 Public Property Filters() As List(Of FiltersClass)
1228 Set(ByVal value As List(Of FiltersClass))
1233 Public Property FilterArray() As FiltersClass()
1235 Return _filters.ToArray
1237 Set(ByVal value As FiltersClass())
1238 For Each filters As FiltersClass In value
1239 _filters.Add(filters)
1244 Public Function Contains(ByVal ID As Long) As Boolean
1245 Return _ids.Contains(ID)
1248 Public Sub ClearIDs()
1251 _oldestUnreadItem = -1
1254 Public Function GetId(ByVal Index As Integer) As Long
1258 Public Function IndexOf(ByVal ID As Long) As Integer
1259 Return _ids.IndexOf(ID)
1262 <Xml.Serialization.XmlIgnore()> _
1263 Public Property FilterModified() As Boolean
1267 Set(ByVal value As Boolean)
1272 Public Function BackupIds() As Long()
1273 Return _ids.ToArray()
1276 Public Property TabName() As String
1280 Set(ByVal value As String)
1285 Public Property TabType() As TabUsageType
1289 Set(ByVal value As TabUsageType)
1296 Public NotInheritable Class FiltersClass
1297 Implements System.IEquatable(Of FiltersClass)
1298 Private _name As String = ""
1299 Private _body As New List(Of String)
1300 Private _searchBoth As Boolean = True
1301 Private _searchUrl As Boolean = False
1302 Private _caseSensitive As Boolean = False
1303 Private _useRegex As Boolean = False
1304 Private _exname As String = ""
1305 Private _exbody As New List(Of String)
1306 Private _exsearchBoth As Boolean = True
1307 Private _exsearchUrl As Boolean = False
1308 Private _exuseRegex As Boolean = False
1309 Private _excaseSensitive As Boolean = False
1310 Private _moveFrom As Boolean = False
1311 Private _setMark As Boolean = True
1313 Public Sub New(ByVal NameFilter As String, _
1314 ByVal BodyFilter As List(Of String), _
1315 ByVal SearchBoth As Boolean, _
1316 ByVal SearchUrl As Boolean, _
1317 ByVal CaseSensitive As Boolean, _
1318 ByVal UseRegex As Boolean, _
1319 ByVal ParentTab As String, _
1320 ByVal ExNameFilter As String, _
1321 ByVal ExBodyFilter As List(Of String), _
1322 ByVal ExSearchBoth As Boolean, _
1323 ByVal ExSearchUrl As Boolean, _
1324 ByVal ExUseRegex As Boolean, _
1325 ByVal ExCaseSensitive As Boolean, _
1326 ByVal MoveFrom As Boolean, _
1327 ByVal SetMark As Boolean)
1330 _searchBoth = SearchBoth
1331 _searchUrl = SearchUrl
1332 _caseSensitive = CaseSensitive
1333 _useRegex = UseRegex
1334 _exname = ExNameFilter
1335 _exbody = ExBodyFilter
1336 _exsearchBoth = ExSearchBoth
1337 _exsearchUrl = ExSearchUrl
1338 _exuseRegex = ExUseRegex
1339 _excaseSensitive = ExCaseSensitive
1340 _moveFrom = MoveFrom
1345 Dim rgx As New Regex(_name)
1346 Catch ex As Exception
1347 Throw New Exception(My.Resources.ButtonOK_ClickText3 + ex.Message)
1350 For Each bs As String In _body
1352 Dim rgx As New Regex(bs)
1353 Catch ex As Exception
1354 Throw New Exception(My.Resources.ButtonOK_ClickText3 + ex.Message)
1361 Dim rgx As New Regex(_exname)
1362 Catch ex As Exception
1363 Throw New Exception(My.Resources.ButtonOK_ClickText3 + ex.Message)
1366 For Each bs As String In _exbody
1368 Dim rgx As New Regex(bs)
1369 Catch ex As Exception
1370 Throw New Exception(My.Resources.ButtonOK_ClickText3 + ex.Message)
1382 Private Function MakeSummary() As String
1383 Dim fs As New System.Text.StringBuilder()
1384 If _name <> "" OrElse _body.Count > 0 Then
1387 fs.AppendFormat(My.Resources.SetFiltersText1, _name)
1389 fs.Append(My.Resources.SetFiltersText2)
1392 If _body.Count > 0 Then
1393 fs.Append(My.Resources.SetFiltersText3)
1394 For Each bf As String In _body
1399 fs.Append(My.Resources.SetFiltersText4)
1403 fs.Append(My.Resources.SetFiltersText5)
1405 fs.Append(My.Resources.SetFiltersText6)
1408 fs.Append(My.Resources.SetFiltersText7)
1411 fs.Append(My.Resources.SetFiltersText8)
1413 If _caseSensitive Then
1414 fs.Append(My.Resources.SetFiltersText13)
1417 ' fs.Append(My.Resources.SetFiltersText9)
1418 'ElseIf _setMark Then
1419 ' fs.Append(My.Resources.SetFiltersText10)
1421 ' fs.Append(My.Resources.SetFiltersText11)
1426 If _exname <> "" OrElse _exbody.Count > 0 Then
1428 fs.Append(My.Resources.SetFiltersText12)
1429 If _exsearchBoth Then
1430 If _exname <> "" Then
1431 fs.AppendFormat(My.Resources.SetFiltersText1, _exname)
1433 fs.Append(My.Resources.SetFiltersText2)
1436 If _exbody.Count > 0 Then
1437 fs.Append(My.Resources.SetFiltersText3)
1438 For Each bf As String In _exbody
1443 fs.Append(My.Resources.SetFiltersText4)
1446 If _exsearchBoth Then
1447 fs.Append(My.Resources.SetFiltersText5)
1449 fs.Append(My.Resources.SetFiltersText6)
1452 fs.Append(My.Resources.SetFiltersText7)
1454 If _exsearchUrl Then
1455 fs.Append(My.Resources.SetFiltersText8)
1457 If _excaseSensitive Then
1458 fs.Append(My.Resources.SetFiltersText13)
1466 fs.Append(My.Resources.SetFiltersText9)
1468 fs.Append(My.Resources.SetFiltersText11)
1470 If Not _moveFrom AndAlso _setMark Then
1471 fs.Append(My.Resources.SetFiltersText10)
1472 ElseIf Not _moveFrom Then
1478 Return fs.ToString()
1481 Public Property NameFilter() As String
1485 Set(ByVal value As String)
1490 Public Property ExNameFilter() As String
1494 Set(ByVal value As String)
1499 <Xml.Serialization.XmlIgnore()> _
1500 Public Property BodyFilter() As List(Of String)
1504 Set(ByVal value As List(Of String))
1509 Public Property BodyFilterArray() As String()
1511 Return _body.ToArray
1513 Set(ByVal value As String())
1514 _body = New List(Of String)
1515 For Each filter As String In value
1521 <Xml.Serialization.XmlIgnore()> _
1522 Public Property ExBodyFilter() As List(Of String)
1526 Set(ByVal value As List(Of String))
1531 Public Property ExBodyFilterArray() As String()
1533 Return _exbody.ToArray
1535 Set(ByVal value As String())
1536 _exbody = New List(Of String)
1537 For Each filter As String In value
1543 Public Property SearchBoth() As Boolean
1547 Set(ByVal value As Boolean)
1552 Public Property ExSearchBoth() As Boolean
1554 Return _exsearchBoth
1556 Set(ByVal value As Boolean)
1557 _exsearchBoth = value
1561 Public Property MoveFrom() As Boolean
1565 Set(ByVal value As Boolean)
1570 Public Property SetMark() As Boolean
1574 Set(ByVal value As Boolean)
1579 Public Property SearchUrl() As Boolean
1583 Set(ByVal value As Boolean)
1588 Public Property ExSearchUrl() As Boolean
1592 Set(ByVal value As Boolean)
1593 _exsearchUrl = value
1597 Public Property CaseSensitive() As Boolean
1599 Return _caseSensitive
1601 Set(ByVal value As Boolean)
1602 _caseSensitive = value
1606 Public Property ExCaseSensitive() As Boolean
1608 Return _excaseSensitive
1610 Set(ByVal value As Boolean)
1611 _excaseSensitive = value
1615 Public Property UseRegex() As Boolean
1619 Set(ByVal value As Boolean)
1624 Public Property ExUseRegex() As Boolean
1628 Set(ByVal value As Boolean)
1633 Public Overrides Function ToString() As String
1634 Return MakeSummary()
1637 Public Function IsHit(ByVal Name As String, ByVal Body As String, ByVal OrgData As String) As HITRESULT
1638 Dim bHit As Boolean = True
1646 Dim compOpt As System.StringComparison
1647 Dim rgOpt As System.Text.RegularExpressions.RegexOptions
1648 If _caseSensitive Then
1649 compOpt = StringComparison.Ordinal
1650 rgOpt = RegexOptions.None
1652 compOpt = StringComparison.OrdinalIgnoreCase
1653 rgOpt = RegexOptions.IgnoreCase
1656 If _name = "" OrElse Name.Equals(_name, compOpt) OrElse _
1657 (_useRegex AndAlso Regex.IsMatch(Name, _name, rgOpt)) Then
1658 For Each fs As String In _body
1660 If Regex.IsMatch(tBody, fs, rgOpt) = False Then bHit = False
1662 If _caseSensitive Then
1663 If tBody.Contains(fs) = False Then bHit = False
1665 If tBody.ToLower().Contains(fs.ToLower()) = False Then bHit = False
1668 If Not bHit Then Exit For
1674 For Each fs As String In _body
1676 If Not (Regex.IsMatch(Name, fs, rgOpt) OrElse _
1677 Regex.IsMatch(tBody, fs, rgOpt)) Then bHit = False
1679 If _caseSensitive Then
1680 If Not (Name.Contains(fs) OrElse _
1681 tBody.Contains(fs)) Then bHit = False
1683 If Not (Name.ToLower().Contains(fs.ToLower()) OrElse _
1684 tBody.ToLower().Contains(fs.ToLower())) Then bHit = False
1687 If Not bHit Then Exit For
1692 Dim exFlag As Boolean = False
1693 'If _name = "" AndAlso _body.Count = 0 Then
1697 If _exname <> "" OrElse _exbody.Count > 0 Then
1698 If _excaseSensitive Then
1699 compOpt = StringComparison.Ordinal
1700 rgOpt = RegexOptions.None
1702 compOpt = StringComparison.OrdinalIgnoreCase
1703 rgOpt = RegexOptions.IgnoreCase
1705 If _exsearchBoth Then
1706 If _exname = "" OrElse Name.Equals(_exname, compOpt) OrElse _
1707 (_exuseRegex AndAlso Regex.IsMatch(Name, _exname, rgOpt)) Then
1708 If _exbody.Count > 0 Then
1709 For Each fs As String In _exbody
1711 If Regex.IsMatch(tBody, fs, rgOpt) Then exFlag = True
1713 If _excaseSensitive Then
1714 If tBody.Contains(fs) Then exFlag = True
1716 If tBody.ToLower().Contains(fs.ToLower()) Then exFlag = True
1719 If exFlag Then Exit For
1726 For Each fs As String In _exbody
1728 If Regex.IsMatch(Name, fs, rgOpt) OrElse _
1729 Regex.IsMatch(tBody, fs, rgOpt) Then exFlag = True
1731 If _excaseSensitive Then
1732 If Name.Contains(fs) OrElse _
1733 tBody.Contains(fs) Then exFlag = True
1735 If Name.ToLower().Contains(fs.ToLower()) OrElse _
1736 tBody.ToLower().Contains(fs.ToLower()) Then exFlag = True
1739 If exFlag Then Exit For
1744 If _name = "" AndAlso _body.Count = 0 Then
1749 'If _setMark Then Return HITRESULT.CopyAndMark
1751 Return HITRESULT.Move
1754 Return HITRESULT.CopyAndMark
1756 Return HITRESULT.Copy
1758 'Return HITRESULT.Copy
1760 Return HITRESULT.Exclude
1764 Return HITRESULT.Exclude
1766 Return HITRESULT.None
1770 Return HITRESULT.None
1774 Public Overloads Function Equals(ByVal other As FiltersClass) As Boolean _
1775 Implements System.IEquatable(Of Tween.FiltersClass).Equals
1777 If Me.BodyFilter.Count <> other.BodyFilter.Count Then Return False
1778 If Me.ExBodyFilter.Count <> other.ExBodyFilter.Count Then Return False
1779 For i As Integer = 0 To Me.BodyFilter.Count - 1
1780 If Me.BodyFilter(i) <> other.BodyFilter(i) Then Return False
1782 For i As Integer = 0 To Me.ExBodyFilter.Count - 1
1783 If Me.ExBodyFilter(i) <> other.ExBodyFilter(i) Then Return False
1786 Return (Me.MoveFrom = other.MoveFrom) And _
1787 (Me.SetMark = other.SetMark) And _
1788 (Me.NameFilter = other.NameFilter) And _
1789 (Me.SearchBoth = other.SearchBoth) And _
1790 (Me.SearchUrl = other.SearchUrl) And _
1791 (Me.UseRegex = other.UseRegex) And _
1792 (Me.ExNameFilter = other.ExNameFilter) And _
1793 (Me.ExSearchBoth = other.ExSearchBoth) And _
1794 (Me.ExSearchUrl = other.ExSearchUrl) And _
1795 (Me.ExUseRegex = other.ExUseRegex)
1798 Public Overrides Function Equals(ByVal obj As Object) As Boolean
1799 If (obj Is Nothing) OrElse Not (Me.GetType() Is obj.GetType()) Then Return False
1800 Return Me.Equals(CType(obj, FiltersClass))
1803 Public Overrides Function GetHashCode() As Integer
1804 Return Me.MoveFrom.GetHashCode Xor _
1805 Me.SetMark.GetHashCode Xor _
1806 Me.BodyFilter.GetHashCode Xor _
1807 Me.NameFilter.GetHashCode Xor _
1808 Me.SearchBoth.GetHashCode Xor _
1809 Me.SearchUrl.GetHashCode Xor _
1810 Me.UseRegex.GetHashCode Xor _
1811 Me.ExBodyFilter.GetHashCode Xor _
1812 Me.ExNameFilter.GetHashCode Xor _
1813 Me.ExSearchBoth.GetHashCode Xor _
1814 Me.ExSearchUrl.GetHashCode Xor _
1815 Me.ExUseRegex.GetHashCode
1820 Public NotInheritable Class IdComparerClass
1821 Implements IComparer(Of Long)
1826 Public Enum ComparerMode
1834 Private _order As SortOrder
1835 Private _mode As ComparerMode
1836 Private _statuses As TabInformations
1837 Private _CmpMethod As Comparison(Of Long)
1840 ''' 昇順か降順か Setの際は同時に比較関数の切り替えを行う
1842 Public Property Order() As SortOrder
1846 Set(ByVal Value As SortOrder)
1848 SetCmpMethod(_mode, _order)
1853 ''' 並び替えの方法 Setの際は同時に比較関数の切り替えを行う
1855 Public Property Mode() As ComparerMode
1859 Set(ByVal Value As ComparerMode)
1861 SetCmpMethod(_mode, _order)
1866 ''' ListViewItemComparerクラスのコンストラクタ(引数付は未使用)
1868 ''' <param name="col">並び替える列番号</param>
1869 ''' <param name="ord">昇順か降順か</param>
1870 ''' <param name="cmod">並び替えの方法</param>
1871 Public Sub New(ByVal ord As SortOrder, ByVal SortMode As ComparerMode)
1874 SetCmpMethod(_mode, _order)
1877 Public Sub New(ByVal TabInf As TabInformations)
1878 _order = SortOrder.Ascending
1879 _mode = ComparerMode.Id
1881 SetCmpMethod(_mode, _order)
1884 ' 指定したソートモードとソートオーダーに従い使用する比較関数のアドレスを返す
1885 Public Overloads ReadOnly Property CmpMethod(ByVal _sortmode As ComparerMode, ByVal _sortorder As SortOrder) As Comparison(Of Long)
1887 Dim _method As Comparison(Of Long) = Nothing
1888 If _sortorder = SortOrder.Ascending Then
1890 Select Case _sortmode
1891 Case ComparerMode.Data
1892 _method = AddressOf Compare_ModeData_Ascending
1893 Case ComparerMode.Id
1894 _method = AddressOf Compare_ModeId_Ascending
1895 Case ComparerMode.Name
1896 _method = AddressOf Compare_ModeName_Ascending
1897 Case ComparerMode.Nickname
1898 _method = AddressOf Compare_ModeNickName_Ascending
1899 Case ComparerMode.Source
1900 _method = AddressOf Compare_ModeSource_Ascending
1904 Select Case _sortmode
1905 Case ComparerMode.Data
1906 _method = AddressOf Compare_ModeData_Descending
1907 Case ComparerMode.Id
1908 _method = AddressOf Compare_ModeId_Descending
1909 Case ComparerMode.Name
1910 _method = AddressOf Compare_ModeName_Descending
1911 Case ComparerMode.Nickname
1912 _method = AddressOf Compare_ModeNickName_Descending
1913 Case ComparerMode.Source
1914 _method = AddressOf Compare_ModeSource_Descending
1921 ' ソートモードとソートオーダーに従い使用する比較関数のアドレスを返す
1922 ' (overload 現在の使用中の比較関数のアドレスを返す)
1923 Public Overloads ReadOnly Property CmpMethod() As Comparison(Of Long)
1929 ' ソートモードとソートオーダーに従い比較関数のアドレスを切り替え
1930 Private Sub SetCmpMethod(ByVal mode As ComparerMode, ByVal order As SortOrder)
1931 _CmpMethod = Me.CmpMethod(mode, order)
1934 'xがyより小さいときはマイナスの数、大きいときはプラスの数、
1935 '同じときは0を返す (こちらは未使用 一応比較関数群呼び出しの形のまま残しておく)
1936 Public Function Compare(ByVal x As Long, ByVal y As Long) _
1937 As Integer Implements IComparer(Of Long).Compare
1938 Return _CmpMethod(x, y)
1941 ' 比較用関数群 いずれもステータスIDの順序を考慮する
1942 ' 注:ID比較でCTypeを使用しているが、abs(x-y)がInteger(Int32)に収まらないことはあり得ないのでこれでよい
1944 Public Function Compare_ModeData_Ascending(ByVal x As Long, ByVal y As Long) As Integer
1945 Dim result As Integer = String.Compare(_statuses.Item(x).Data, _statuses.Item(y).Data)
1946 If result = 0 Then result = x.CompareTo(y)
1951 Public Function Compare_ModeData_Descending(ByVal x As Long, ByVal y As Long) As Integer
1952 Dim result As Integer = String.Compare(_statuses.Item(y).Data, _statuses.Item(x).Data)
1953 If result = 0 Then result = y.CompareTo(x)
1958 Public Function Compare_ModeId_Ascending(ByVal x As Long, ByVal y As Long) As Integer
1959 Return x.CompareTo(y)
1963 Public Function Compare_ModeId_Descending(ByVal x As Long, ByVal y As Long) As Integer
1964 Return y.CompareTo(x)
1968 Public Function Compare_ModeName_Ascending(ByVal x As Long, ByVal y As Long) As Integer
1969 Dim result As Integer = String.Compare(_statuses.Item(x).Name, _statuses.Item(y).Name)
1970 If result = 0 Then result = x.CompareTo(y)
1975 Public Function Compare_ModeName_Descending(ByVal x As Long, ByVal y As Long) As Integer
1976 Dim result As Integer = String.Compare(_statuses.Item(y).Name, _statuses.Item(x).Name)
1977 If result = 0 Then result = y.CompareTo(x)
1982 Public Function Compare_ModeNickName_Ascending(ByVal x As Long, ByVal y As Long) As Integer
1983 Dim result As Integer = String.Compare(_statuses.Item(x).Nickname, _statuses.Item(y).Nickname)
1984 If result = 0 Then result = x.CompareTo(y)
1989 Public Function Compare_ModeNickName_Descending(ByVal x As Long, ByVal y As Long) As Integer
1990 Dim result As Integer = String.Compare(_statuses.Item(y).Nickname, _statuses.Item(x).Nickname)
1991 If result = 0 Then result = y.CompareTo(x)
1996 Public Function Compare_ModeSource_Ascending(ByVal x As Long, ByVal y As Long) As Integer
1997 Dim result As Integer = String.Compare(_statuses.Item(x).Source, _statuses.Item(y).Source)
1998 If result = 0 Then result = x.CompareTo(y)
2003 Public Function Compare_ModeSource_Descending(ByVal x As Long, ByVal y As Long) As Integer
2004 Dim result As Integer = String.Compare(_statuses.Item(y).Source, _statuses.Item(x).Source)
2005 If result = 0 Then result = y.CompareTo(x)