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
28 Imports System.Web.HttpUtility
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 = ""
55 Private _RetweetedId As Long = 0
66 Public Sub New(ByVal Nickname As String, _
67 ByVal Data As String, _
68 ByVal OriginalData As String, _
69 ByVal ImageUrl As String, _
70 ByVal Name As String, _
71 ByVal PDate As Date, _
73 ByVal IsFav As Boolean, _
74 ByVal IsRead As Boolean, _
75 ByVal IsReply As Boolean, _
76 ByVal IsProtect As Boolean, _
77 ByVal IsOwl As Boolean, _
78 ByVal IsMark As Boolean, _
79 ByVal InReplyToUser As String, _
80 ByVal InReplyToId As Long, _
81 ByVal Source As String, _
82 ByVal ReplyToList As List(Of String), _
83 ByVal IsMe As Boolean, _
84 ByVal ImageIndex As Integer, _
85 ByVal IsDm As Boolean, _
87 ByVal FilterHit As Boolean, _
88 ByVal RetweetedBy As String, _
89 ByVal RetweetedId As Long)
97 _OrgData = OriginalData
100 _IsProtect = IsProtect
103 _InReplyToUser = InReplyToUser
104 _InReplyToId = InReplyToId
106 _ReplyToList = ReplyToList
108 _ImageIndex = ImageIndex
111 _FilterHit = FilterHit
112 _RetweetedBy = RetweetedBy
113 _RetweetedId = RetweetedId
119 Public Property Nickname() As String
123 Set(ByVal value As String)
127 Public Property Data() As String
131 Set(ByVal value As String)
135 Public Property ImageUrl() As String
139 Set(ByVal value As String)
143 Public Property Name() As String
147 Set(ByVal value As String)
151 Public Property PDate() As Date
155 Set(ByVal value As Date)
159 Public Property Id() As Long
163 Set(ByVal value As Long)
167 Public Property IsFav() As Boolean
169 If Me.RetweetedId > 0 AndAlso TabInformations.GetInstance.RetweetSource(Me.RetweetedId) IsNot Nothing Then
170 Return TabInformations.GetInstance.RetweetSource(Me.RetweetedId).IsFav
175 Set(ByVal value As Boolean)
177 If Me.RetweetedId > 0 AndAlso TabInformations.GetInstance.RetweetSource(Me.RetweetedId) IsNot Nothing Then
178 TabInformations.GetInstance.RetweetSource(Me.RetweetedId).IsFav = value
182 Public Property OriginalData() As String
186 Set(ByVal value As String)
190 Public Property IsRead() As Boolean
194 Set(ByVal value As Boolean)
196 _statuses = _statuses Or Statuses.Read
198 _statuses = _statuses And Not Statuses.Read
203 Public Property IsReply() As Boolean
207 Set(ByVal value As Boolean)
211 Public Property IsProtect() As Boolean
215 Set(ByVal value As Boolean)
217 _statuses = _statuses Or Statuses.Protect
219 _statuses = _statuses And Not Statuses.Protect
224 Public Property IsOwl() As Boolean
228 Set(ByVal value As Boolean)
232 Public Property IsMark() As Boolean
236 Set(ByVal value As Boolean)
238 _statuses = _statuses Or Statuses.Mark
240 _statuses = _statuses And Not Statuses.Mark
245 Public Property InReplyToUser() As String
247 Return _InReplyToUser
249 Set(ByVal value As String)
250 _InReplyToUser = value
253 Public Property InReplyToId() As Long
257 Set(ByVal value As Long)
261 Public Property Source() As String
265 Set(ByVal value As String)
269 Public Property ReplyToList() As List(Of String)
273 Set(ByVal value As List(Of String))
277 Public Property IsMe() As Boolean
281 Set(ByVal value As Boolean)
285 Public Property ImageIndex() As Integer
289 Set(ByVal value As Integer)
293 Public Property IsDm() As Boolean
297 Set(ByVal value As Boolean)
301 Public ReadOnly Property StatusIndex() As Integer
306 Public Property Uid() As Long
310 Set(ByVal value As Long)
314 Public Property FilterHit() As Boolean
318 Set(ByVal value As Boolean)
322 Public Property RetweetedBy() As String
326 Set(ByVal value As String)
330 Public Property RetweetedId() As Long
334 Set(ByVal value As Long)
340 Public NotInheritable Class TabInformations
341 '個別タブの情報をDictionaryで保持
342 Private _sorter As IdComparerClass
343 Private _tabs As New Dictionary(Of String, TabClass)
344 Private _statuses As New Dictionary(Of Long, PostClass)
345 Private _addedIds As List(Of Long)
346 Private _retweets As New Dictionary(Of Long, PostClass)
349 'AddPost(複数回) -> DistributePosts -> SubmitUpdate
352 Private _addCount As Integer
353 Private _soundFile As String
354 Private _notifyPosts As List(Of PostClass)
355 Private ReadOnly LockObj As New Object
356 Private ReadOnly LockUnread As New Object
358 Private Shared _instance As TabInformations = New TabInformations
361 _sorter = New IdComparerClass(Me)
364 Public Shared Function GetInstance() As TabInformations
365 Return _instance 'singleton
368 Public Sub AddTab(ByVal TabName As String, ByVal TabType As TabUsageType)
369 _tabs.Add(TabName, New TabClass(TabName, TabType))
372 Public Sub AddTab(ByVal TabName As String, ByVal Tab As TabClass)
373 _tabs.Add(TabName, Tab)
376 Public Sub RemoveTab(ByVal TabName As String)
378 If IsDefaultTab(TabName) Then Exit Sub '念のため
379 Dim homeTab As TabClass = GetTabByType(TabUsageType.Home)
380 Dim dmName As String = GetTabByType(TabUsageType.DirectMessage).TabName
382 For idx As Integer = 0 To _tabs(TabName).AllCount - 1
383 Dim exist As Boolean = False
384 Dim Id As Long = _tabs(TabName).GetId(idx)
385 For Each key As String In _tabs.Keys
386 If Not key = TabName AndAlso key <> dmName Then
387 If _tabs(key).Contains(Id) Then
393 If Not exist Then homeTab.Add(Id, _statuses(Id).IsRead, False)
396 _tabs.Remove(TabName)
400 Public Function ContainsTab(ByVal TabText As String) As Boolean
401 Return _tabs.ContainsKey(TabText)
404 Public Function ContainsTab(ByVal ts As TabClass) As Boolean
405 Return _tabs.ContainsValue(ts)
408 Public Property Tabs() As Dictionary(Of String, TabClass)
412 Set(ByVal value As Dictionary(Of String, TabClass))
417 Public ReadOnly Property KeysTab() As Collections.Generic.Dictionary(Of String, TabClass).KeyCollection
423 Public Sub SortPosts()
424 For Each key As String In _tabs.Keys
425 _tabs(key).Sort(_sorter)
429 Public ReadOnly Property Sorter() As IdComparerClass
435 Public Property SortOrder() As SortOrder
439 Set(ByVal value As SortOrder)
440 _sorter.Order = value
444 Public Property SortMode() As IdComparerClass.ComparerMode
448 Set(ByVal value As IdComparerClass.ComparerMode)
453 Public Sub ToggleSortOrder(ByVal SortMode As IdComparerClass.ComparerMode)
454 If _sorter.Mode = SortMode Then
455 If _sorter.Order = Windows.Forms.SortOrder.Ascending Then
456 _sorter.Order = Windows.Forms.SortOrder.Descending
458 _sorter.Order = Windows.Forms.SortOrder.Ascending
461 _sorter.Mode = SortMode
462 _sorter.Order = Windows.Forms.SortOrder.Ascending
467 Public ReadOnly Property RetweetSource(ByVal Id As Long) As PostClass
469 If _retweets.ContainsKey(Id) Then
477 Public Sub RemovePost(ByVal Name As String, ByVal Id As Long)
479 Dim post As PostClass = _statuses(Id)
481 Dim tab As TabClass = _tabs(Name)
482 Dim tType As TabUsageType = tab.TabType
483 If tab.Contains(Id) Then
484 If tab.UnreadManage AndAlso Not post.IsRead Then '未読管理
487 Me.SetNextUnreadId(Id, tab)
492 'FavタブからRetweet発言を削除する場合は、他の同一参照Retweetも削除
493 If tType = TabUsageType.Favorites AndAlso post.RetweetedId > 0 Then
494 For i As Integer = 0 To tab.AllCount - 1
495 Dim rPost As PostClass = Me.Item(Name, i)
496 If rPost.RetweetedId > 0 AndAlso rPost.RetweetedId = post.RetweetedId Then
497 If tab.UnreadManage AndAlso Not rPost.IsRead Then '未読管理
500 Me.SetNextUnreadId(rPost.Id, tab)
510 Public Sub RemovePost(ByVal Id As Long)
512 Dim post As PostClass = _statuses(Id)
514 For Each key As String In _tabs.Keys
515 Dim tab As TabClass = _tabs(key)
516 If tab.Contains(Id) Then
517 If tab.UnreadManage AndAlso Not post.IsRead Then '未読管理
520 Me.SetNextUnreadId(Id, tab)
530 Public Function GetOldestUnreadId(ByVal TabName As String) As Integer
531 Dim tb As TabClass = _tabs(TabName)
532 If tb.OldestUnreadId > -1 AndAlso _
533 tb.Contains(tb.OldestUnreadId) AndAlso _
534 tb.UnreadCount > 0 Then
536 If _statuses.Item(tb.OldestUnreadId).IsRead Then
539 Me.SetNextUnreadId(-1, tb) '頭から探索
541 If tb.OldestUnreadId = -1 Then
544 Return tb.IndexOf(tb.OldestUnreadId)
547 Return tb.IndexOf(tb.OldestUnreadId) '最短経路
550 '一見未読なさそうだが、未読カウントはあるので探索
551 If tb.UnreadCount > 0 Then
553 Me.SetNextUnreadId(-1, tb)
555 If tb.OldestUnreadId = -1 Then
558 Return tb.IndexOf(tb.OldestUnreadId)
566 Private Sub SetNextUnreadId(ByVal CurrentId As Long, ByVal Tab As TabClass)
567 'CurrentID:今既読にしたID(OldestIDの可能性あり)
568 '最古未読が設定されていて、既読の場合(1発言以上存在)
570 If Tab.OldestUnreadId > -1 AndAlso _
571 _statuses.ContainsKey(Tab.OldestUnreadId) AndAlso _
572 _statuses.Item(Tab.OldestUnreadId).IsRead AndAlso _
573 _sorter.Mode = IdComparerClass.ComparerMode.Id Then '次の未読探索
574 If Tab.UnreadCount = 0 Then
576 Tab.OldestUnreadId = -1
577 ElseIf Tab.OldestUnreadId = CurrentId Then
578 '最古IDを既読にしたタイミング→次のIDから続けて探索
579 Dim idx As Integer = Tab.IndexOf(CurrentId)
582 FindUnreadId(idx, Tab)
585 FindUnreadId(-1, Tab)
589 FindUnreadId(-1, Tab)
593 FindUnreadId(-1, Tab)
595 Catch ex As Generic.KeyNotFoundException
597 FindUnreadId(-1, Tab)
601 Private Sub FindUnreadId(ByVal StartIdx As Integer, ByVal Tab As TabClass)
602 If Tab.AllCount = 0 Then
603 Tab.OldestUnreadId = -1
607 Dim toIdx As Integer = 0
608 Dim stp As Integer = 1
609 Tab.OldestUnreadId = -1
610 If _sorter.Order = Windows.Forms.SortOrder.Ascending Then
611 If StartIdx = -1 Then
615 If StartIdx > Tab.AllCount - 1 Then StartIdx = Tab.AllCount - 1 '念のため
617 toIdx = Tab.AllCount - 1
618 If toIdx < 0 Then toIdx = 0 '念のため
621 If StartIdx = -1 Then
622 StartIdx = Tab.AllCount - 1
626 If StartIdx < 0 Then StartIdx = 0 '念のため
630 For i As Integer = StartIdx To toIdx Step stp
631 If Not _statuses(Tab.GetId(i)).IsRead Then
632 Tab.OldestUnreadId = Tab.GetId(i)
638 Public Function DistributePosts() As Integer
641 If _addedIds Is Nothing Then Return 0
642 If _addedIds.Count = 0 Then Return 0
644 If _notifyPosts Is Nothing Then _notifyPosts = New List(Of PostClass)
645 Me.Distribute() 'タブに仮振分
646 _addCount = _addedIds.Count
648 _addedIds = Nothing '後始末
653 Public Function SubmitUpdate(ByRef soundFile As String, ByRef notifyPosts As PostClass()) As Integer
656 If _notifyPosts Is Nothing Then
658 notifyPosts = Nothing
662 For Each key As String In _tabs.Keys
663 _tabs(key).AddSubmit() '振分確定(各タブに反映)
667 soundFile = _soundFile
669 notifyPosts = _notifyPosts.ToArray()
671 _notifyPosts = Nothing
672 Dim retCnt As Integer = _addCount
674 Return retCnt '件数(EndUpdateの戻り値と同じ)
678 Private Sub Distribute()
679 '各タブのフィルターと照合。合致したらタブにID追加
680 '通知メッセージ用に、表示必要な発言リストと再生サウンドを返す
681 'notifyPosts = New List(Of PostClass)
682 Dim homeTab As TabClass = GetTabByType(TabUsageType.Home)
683 Dim replyTab As TabClass = GetTabByType(TabUsageType.Mentions)
684 Dim dmTab As TabClass = GetTabByType(TabUsageType.DirectMessage)
685 Dim favTab As TabClass = GetTabByType(TabUsageType.Favorites)
686 For Each id As Long In _addedIds
687 Dim post As PostClass = _statuses(id)
688 If Not post.IsDm Then
689 Dim add As Boolean = False '通知リスト追加フラグ
690 Dim mv As Boolean = False '移動フラグ(Recent追加有無)
691 For Each tn As String In _tabs.Keys
692 Dim rslt As HITRESULT = HITRESULT.None
693 If post.RetweetedId = 0 Then
694 rslt = _tabs(tn).AddFiltered(post.Id, post.IsRead, post.Name, post.Data, post.OriginalData)
696 rslt = _tabs(tn).AddFiltered(post.Id, post.IsRead, post.RetweetedBy, post.Data, post.OriginalData)
698 If rslt <> HITRESULT.None Then
699 If rslt = HITRESULT.CopyAndMark Then post.IsMark = True 'マークあり
700 If rslt = HITRESULT.Move Then
704 If _tabs(tn).Notify Then add = True '通知あり
705 If Not _tabs(tn).SoundFile = "" AndAlso _soundFile = "" Then
706 _soundFile = _tabs(tn).SoundFile 'wavファイル(未設定の場合のみ)
708 post.FilterHit = True
710 post.FilterHit = False
713 If Not mv Then '移動されなかったらRecentに追加
714 homeTab.Add(post.Id, post.IsRead, True)
715 If Not homeTab.SoundFile = "" AndAlso _soundFile = "" Then _soundFile = homeTab.SoundFile
716 If homeTab.Notify Then add = True
718 If post.IsReply Then 'ReplyだったらReplyタブに追加
719 replyTab.Add(post.Id, post.IsRead, True)
720 If Not replyTab.SoundFile = "" Then _soundFile = replyTab.SoundFile
721 If replyTab.Notify Then add = True
723 If post.IsFav Then 'Fav済み発言だったらFavoritesタブに追加
724 If favTab.Contains(post.Id) Then
729 favTab.Add(post.Id, post.IsRead, True)
730 If Not favTab.SoundFile = "" Then _soundFile = favTab.SoundFile
731 If favTab.Notify Then add = True
734 If add Then _notifyPosts.Add(post)
736 dmTab.Add(post.Id, post.IsRead, True)
737 If dmTab.Notify Then _notifyPosts.Add(post)
738 _soundFile = dmTab.SoundFile
743 Public Sub AddPost(ByVal Item As PostClass)
745 If _statuses.ContainsKey(Item.Id) Then
747 _statuses.Item(Item.Id).IsFav = True
749 Exit Sub '追加済みなら何もしない
752 _statuses.Add(Item.Id, Item) 'DMと区別しない?
754 If Item.RetweetedId > 0 Then
755 If Not _retweets.ContainsKey(Item.RetweetedId) Then
759 If Item.IsFav AndAlso _retweets.ContainsKey(Item.Id) Then
760 Exit Sub 'Fav済みのRetweet元発言は追加しない
762 If _addedIds Is Nothing Then _addedIds = New List(Of Long) 'タブ追加用IDコレクション準備
763 _addedIds.Add(Item.Id)
767 Private Sub AddRetweet(ByVal item As PostClass)
784 item.InReplyToUser, _
799 Public Sub SetRead(ByVal Read As Boolean, ByVal TabName As String, ByVal Index As Integer)
800 'Read:True=既読へ False=未読へ
801 Dim tb As TabClass = _tabs(TabName)
803 If tb.UnreadManage = False Then Exit Sub '未読管理していなければ終了
805 Dim Id As Long = tb.GetId(Index)
807 If _statuses(Id).IsRead = Read Then Exit Sub '状態変更なければ終了
809 _statuses(Id).IsRead = Read '指定の状態に変更
814 Me.SetNextUnreadId(Id, tb) '次の未読セット
815 '他タブの最古未読IDはタブ切り替え時に。
816 For Each key As String In _tabs.Keys
817 If key <> TabName AndAlso _
818 _tabs(key).UnreadManage AndAlso _
819 _tabs(key).Contains(Id) Then
820 _tabs(key).UnreadCount -= 1
821 If _tabs(key).OldestUnreadId = Id Then _tabs(key).OldestUnreadId = -1
826 If tb.OldestUnreadId > Id OrElse tb.OldestUnreadId = -1 Then tb.OldestUnreadId = Id
827 For Each key As String In _tabs.Keys
828 If Not key = TabName AndAlso _tabs(key).UnreadManage AndAlso _tabs(key).Contains(Id) Then
829 _tabs(key).UnreadCount += 1
830 If _tabs(key).OldestUnreadId > Id Then _tabs(key).OldestUnreadId = Id
838 Dim tb As TabClass = GetTabByType(TabUsageType.Home)
839 If tb.UnreadManage = False Then Exit Sub
841 For i As Integer = 0 To tb.AllCount - 1
842 Dim id As Long = tb.GetId(i)
843 If Not _statuses(id).IsDm AndAlso _
844 Not _statuses(id).IsReply AndAlso _
845 Not _statuses(id).IsRead AndAlso _
846 Not _statuses(id).FilterHit Then
847 _statuses(id).IsRead = True
848 Me.SetNextUnreadId(id, tb) '次の未読セット
849 For Each key As String In _tabs.Keys
850 If _tabs(key).UnreadManage AndAlso _
851 _tabs(key).Contains(id) Then
852 _tabs(key).UnreadCount -= 1
853 If _tabs(key).OldestUnreadId = id Then _tabs(key).OldestUnreadId = -1
860 Public ReadOnly Property Item(ByVal ID As Long) As PostClass
866 Public ReadOnly Property Item(ByVal TabName As String, ByVal Index As Integer) As PostClass
868 Return _statuses(_tabs(TabName).GetId(Index))
872 Public ReadOnly Property Item(ByVal TabName As String, ByVal StartIndex As Integer, ByVal EndIndex As Integer) As PostClass()
874 Dim length As Integer = EndIndex - StartIndex + 1
875 Dim posts() As PostClass = New PostClass(length - 1) {}
876 For i As Integer = 0 To length - 1
877 posts(i) = _statuses(_tabs(TabName).GetId(StartIndex + i))
883 Public ReadOnly Property ItemCount() As Integer
886 Return _statuses.Count
891 Public Function ContainsKey(ByVal Id As Long) As Boolean
893 Return _statuses.ContainsKey(Id)
897 Public Sub SetUnreadManage(ByVal Manage As Boolean)
899 For Each key As String In _tabs.Keys
900 Dim tb As TabClass = _tabs(key)
901 If tb.UnreadManage Then
903 Dim cnt As Integer = 0
904 Dim oldest As Long = Long.MaxValue
905 For Each id As Long In tb.BackupIds
906 If Not _statuses(id).IsRead Then
908 If oldest > id Then oldest = id
911 tb.OldestUnreadId = oldest
917 For Each key As String In _tabs.Keys
918 Dim tb As TabClass = _tabs(key)
919 If tb.UnreadManage AndAlso tb.UnreadCount > 0 Then
922 tb.OldestUnreadId = -1
929 Public Sub RenameTab(ByVal Original As String, ByVal NewName As String)
930 Dim tb As TabClass = _tabs(Original)
931 _tabs.Remove(Original)
933 _tabs.Add(NewName, tb)
936 Public Sub FilterAll()
938 Dim tbr As TabClass = GetTabByType(TabUsageType.Home)
939 Dim replyTab As TabClass = GetTabByType(TabUsageType.Mentions)
940 For Each key As String In _tabs.Keys
941 Dim tb As TabClass = _tabs(key)
942 If tb.FilterModified Then
943 tb.FilterModified = False
944 Dim orgIds() As Long = tb.BackupIds()
946 ''''''''''''''フィルター前のIDsを退避。どのタブにも含まれないidはrecentへ追加
947 ''''''''''''''moveフィルターにヒットした際、recentに該当あればrecentから削除
948 For Each id As Long In _statuses.Keys
949 Dim post As PostClass = _statuses.Item(id)
950 If post.IsDm Then Continue For
951 Dim rslt As HITRESULT = HITRESULT.None
952 If post.RetweetedId = 0 Then
953 rslt = tb.AddFiltered(post.Id, post.IsRead, post.Name, post.Data, post.OriginalData)
955 rslt = tb.AddFiltered(post.Id, post.IsRead, post.RetweetedBy, post.Data, post.OriginalData)
958 Case HITRESULT.CopyAndMark
959 post.IsMark = True 'マークあり
960 post.FilterHit = True
962 tbr.Remove(post.Id, post.IsRead)
964 post.FilterHit = True
967 post.FilterHit = True
969 If key = replyTab.TabName AndAlso post.IsReply Then replyTab.Add(post.Id, post.IsRead, True)
970 If post.IsFav Then GetTabByType(TabUsageType.Favorites).Add(post.Id, post.IsRead, True)
971 post.FilterHit = False
975 For Each id As Long In orgIds
976 Dim hit As Boolean = False
977 For Each tkey As String In _tabs.Keys
978 If _tabs(tkey).Contains(id) Then
983 If Not hit Then tbr.Add(id, _statuses(id).IsRead, False)
992 Public Function GetId(ByVal TabName As String, ByVal IndexCollection As ListView.SelectedIndexCollection) As Long()
993 If IndexCollection.Count = 0 Then Return Nothing
995 Dim tb As TabClass = _tabs(TabName)
996 Dim Ids(IndexCollection.Count - 1) As Long
997 For i As Integer = 0 To Ids.Length - 1
998 Ids(i) = tb.GetId(IndexCollection(i))
1003 Public Function GetId(ByVal TabName As String, ByVal Index As Integer) As Long
1004 Return _tabs(TabName).GetId(Index)
1007 Public Function IndexOf(ByVal TabName As String, ByVal Ids() As Long) As Integer()
1008 If Ids Is Nothing Then Return Nothing
1009 Dim idx(Ids.Length - 1) As Integer
1010 Dim tb As TabClass = _tabs(TabName)
1011 For i As Integer = 0 To Ids.Length - 1
1012 idx(i) = tb.IndexOf(Ids(i))
1017 Public Function IndexOf(ByVal TabName As String, ByVal Id As Long) As Integer
1018 Return _tabs(TabName).IndexOf(Id)
1021 Public Sub ClearTabIds(ByVal TabName As String)
1023 For Each Id As Long In _tabs(TabName).BackupIds
1024 Dim Hit As Boolean = False
1025 For Each tb As TabClass In _tabs.Values
1026 If tb.Contains(Id) Then
1031 If Not Hit Then _statuses.Remove(Id)
1034 _tabs(TabName).ClearIDs()
1037 Public Sub SetTabUnreadManage(ByVal TabName As String, ByVal Manage As Boolean)
1038 Dim tb As TabClass = _tabs(TabName)
1041 Dim cnt As Integer = 0
1042 Dim oldest As Long = Long.MaxValue
1043 For Each id As Long In tb.BackupIds
1044 If Not _statuses(id).IsRead Then
1046 If oldest > id Then oldest = id
1049 tb.OldestUnreadId = oldest
1050 tb.UnreadCount = cnt
1052 tb.OldestUnreadId = -1
1056 tb.UnreadManage = Manage
1059 Public Sub RefreshOwl(ByVal follower As List(Of String))
1061 If follower.Count > 1 Then
1062 For Each id As Long In _statuses.Keys
1063 If Not _statuses(id).IsDm Then _statuses(id).IsOwl = Not follower.Contains(_statuses(id).Name.ToLower())
1066 For Each id As Long In _statuses.Keys
1067 If Not _statuses(id).IsDm Then _statuses(id).IsOwl = False
1073 Public Function GetTabByType(ByVal tabType As TabUsageType) As TabClass
1074 'Home,Mentions,DM,Favは1つに制限する
1075 'その他のタイプを指定されたら、最初に合致したものを返す
1077 For Each tb As TabClass In _tabs.Values
1078 If tb.TabType = tabType Then Return tb
1084 Public Function IsDefaultTab(ByVal tabName As String) As Boolean
1085 If tabName IsNot Nothing AndAlso _
1086 _tabs.ContainsKey(tabName) AndAlso _
1087 (_tabs(tabName).TabType = TabUsageType.Home OrElse _
1088 _tabs(tabName).TabType = TabUsageType.Mentions OrElse _
1089 _tabs(tabName).TabType = TabUsageType.DirectMessage OrElse _
1090 _tabs(tabName).TabType = TabUsageType.Favorites) Then
1099 Public NotInheritable Class TabClass
1100 Private _unreadManage As Boolean = False
1101 Private _notify As Boolean = False
1102 Private _soundFile As String = ""
1103 Private _filters As List(Of FiltersClass)
1104 Private _oldestUnreadItem As Long = -1 'ID
1105 Private _unreadCount As Integer = 0
1106 Private _ids As List(Of Long)
1107 Private _filterMod As Boolean = False
1108 Private _tmpIds As List(Of TempolaryId)
1109 Private _tabName As String = ""
1110 Private _tabType As TabUsageType = TabUsageType.Undefined
1113 Private _searchLang As String = ""
1114 Private _searchSource As String = ""
1115 Private _searchLinks As Boolean = False
1116 Private _searchWords As String = ""
1118 Public Property SearchLang() As String
1122 Set(ByVal value As String)
1126 Public Property SearchSource() As String
1128 Return _searchSource
1130 Set(ByVal value As String)
1131 _searchSource = value
1134 Public Property SearchLinks() As Boolean
1138 Set(ByVal value As Boolean)
1139 _searchLinks = value
1142 Public Property SearchWords() As String
1146 Set(ByVal value As String)
1147 _searchWords = value.Trim
1150 Public ReadOnly Property SearchQuery() As String
1152 Dim qry As String = ""
1153 If String.IsNullOrEmpty(_searchWords) Then Return ""
1154 qry = "q=" + _searchWords
1155 If Not String.IsNullOrEmpty(_searchSource) Then qry += " source:" + _searchSource
1156 If _searchLinks Then qry += " filter:links"
1157 If Not String.IsNullOrEmpty(_searchLang) Then qry += "&lang=" + _searchLang
1158 Return UrlEncode(qry)
1162 Private Structure TempolaryId
1164 Public Read As Boolean
1166 Public Sub New(ByVal argId As Long, ByVal argRead As Boolean)
1173 _filters = New List(Of FiltersClass)
1176 _unreadManage = True
1177 _ids = New List(Of Long)
1178 _oldestUnreadItem = -1
1179 _tabType = TabUsageType.Undefined
1182 Public Sub New(ByVal TabName As String, ByVal TabType As TabUsageType)
1184 _filters = New List(Of FiltersClass)
1187 _unreadManage = True
1188 _ids = New List(Of Long)
1189 _oldestUnreadItem = -1
1193 Public Sub Sort(ByVal Sorter As IdComparerClass)
1194 _ids.Sort(Sorter.CmpMethod)
1198 Private Sub Add(ByVal ID As Long, ByVal Read As Boolean)
1199 If Me._ids.Contains(ID) Then Exit Sub
1203 If Not Read AndAlso Me._unreadManage Then
1204 Me._unreadCount += 1
1205 If Me._oldestUnreadItem = -1 Then
1206 Me._oldestUnreadItem = ID
1208 If ID < Me._oldestUnreadItem Then Me._oldestUnreadItem = ID
1213 Public Sub Add(ByVal ID As Long, ByVal Read As Boolean, ByVal Temporary As Boolean)
1214 If Not Temporary Then
1217 If _tmpIds Is Nothing Then _tmpIds = New List(Of TempolaryId)
1218 _tmpIds.Add(New TempolaryId(ID, Read))
1223 Public Function AddFiltered(ByVal ID As Long, _
1224 ByVal Read As Boolean, _
1225 ByVal Name As String, _
1226 ByVal Body As String, _
1227 ByVal OrgData As String) As HITRESULT
1229 ' rwLock.AcquireReaderLock(System.Threading.Timeout.Infinite) '読み取りロック取得
1231 Dim rslt As HITRESULT = HITRESULT.None
1233 For Each ft As FiltersClass In _filters
1234 Select Case ft.IsHit(Name, Body, OrgData) 'フィルタクラスでヒット判定
1237 If rslt <> HITRESULT.CopyAndMark Then rslt = HITRESULT.Copy
1238 Case HITRESULT.CopyAndMark
1239 rslt = HITRESULT.CopyAndMark
1241 rslt = HITRESULT.Move
1242 Case HITRESULT.Exclude
1243 rslt = HITRESULT.None
1248 If rslt <> HITRESULT.None Then
1249 If _tmpIds Is Nothing Then _tmpIds = New List(Of TempolaryId)
1250 _tmpIds.Add(New TempolaryId(ID, Read))
1254 Return rslt 'マーク付けは呼び出し元で行うこと
1257 ' rwLock.ReleaseReaderLock()
1261 Public Sub AddSubmit()
1262 If _tmpIds Is Nothing Then Exit Sub
1263 For Each tId As TempolaryId In _tmpIds
1264 Me.Add(tId.Id, tId.Read)
1270 Public Sub Remove(ByVal Id As Long)
1271 If Not Me._ids.Contains(Id) Then Exit Sub
1276 Public Sub Remove(ByVal Id As Long, ByVal Read As Boolean)
1277 If Not Me._ids.Contains(Id) Then Exit Sub
1279 If Not Read AndAlso Me._unreadManage Then
1280 Me._unreadCount -= 1
1281 Me._oldestUnreadItem = -1
1287 Public Property UnreadManage() As Boolean
1289 Return _unreadManage
1291 Set(ByVal value As Boolean)
1292 Me._unreadManage = value
1294 Me._oldestUnreadItem = -1
1300 Public Property Notify() As Boolean
1304 Set(ByVal value As Boolean)
1309 Public Property SoundFile() As String
1313 Set(ByVal value As String)
1318 <Xml.Serialization.XmlIgnore()> _
1319 Public Property OldestUnreadId() As Long
1321 Return _oldestUnreadItem
1323 Set(ByVal value As Long)
1324 _oldestUnreadItem = value
1328 <Xml.Serialization.XmlIgnore()> _
1329 Public Property UnreadCount() As Integer
1333 Set(ByVal value As Integer)
1334 _unreadCount = value
1338 Public ReadOnly Property AllCount() As Integer
1340 Return Me._ids.Count
1344 Public Function GetFilters() As FiltersClass()
1345 Return _filters.ToArray()
1348 Public Sub RemoveFilter(ByVal filter As FiltersClass)
1349 _filters.Remove(filter)
1353 Public Function AddFilter(ByVal filter As FiltersClass) As Boolean
1354 If _filters.Contains(filter) Then Return False
1355 _filters.Add(filter)
1360 Public Sub EditFilter(ByVal original As FiltersClass, ByVal modified As FiltersClass)
1361 original.BodyFilter = modified.BodyFilter
1362 original.NameFilter = modified.NameFilter
1363 original.SearchBoth = modified.SearchBoth
1364 original.SearchUrl = modified.SearchUrl
1365 original.UseRegex = modified.UseRegex
1366 original.CaseSensitive = modified.CaseSensitive
1367 original.ExBodyFilter = modified.ExBodyFilter
1368 original.ExNameFilter = modified.ExNameFilter
1369 original.ExSearchBoth = modified.ExSearchBoth
1370 original.ExSearchUrl = modified.ExSearchUrl
1371 original.ExUseRegex = modified.ExUseRegex
1372 original.ExCaseSensitive = modified.ExCaseSensitive
1373 original.MoveFrom = modified.MoveFrom
1374 original.SetMark = modified.SetMark
1378 <Xml.Serialization.XmlIgnore()> _
1379 Public Property Filters() As List(Of FiltersClass)
1383 Set(ByVal value As List(Of FiltersClass))
1388 Public Property FilterArray() As FiltersClass()
1390 Return _filters.ToArray
1392 Set(ByVal value As FiltersClass())
1393 For Each filters As FiltersClass In value
1394 _filters.Add(filters)
1399 Public Function Contains(ByVal ID As Long) As Boolean
1400 Return _ids.Contains(ID)
1403 Public Sub ClearIDs()
1406 _oldestUnreadItem = -1
1409 Public Function GetId(ByVal Index As Integer) As Long
1413 Public Function IndexOf(ByVal ID As Long) As Integer
1414 Return _ids.IndexOf(ID)
1417 <Xml.Serialization.XmlIgnore()> _
1418 Public Property FilterModified() As Boolean
1422 Set(ByVal value As Boolean)
1427 Public Function BackupIds() As Long()
1428 Return _ids.ToArray()
1431 Public Property TabName() As String
1435 Set(ByVal value As String)
1440 Public Property TabType() As TabUsageType
1444 Set(ByVal value As TabUsageType)
1451 Public NotInheritable Class FiltersClass
1452 Implements System.IEquatable(Of FiltersClass)
1453 Private _name As String = ""
1454 Private _body As New List(Of String)
1455 Private _searchBoth As Boolean = True
1456 Private _searchUrl As Boolean = False
1457 Private _caseSensitive As Boolean = False
1458 Private _useRegex As Boolean = False
1459 Private _exname As String = ""
1460 Private _exbody As New List(Of String)
1461 Private _exsearchBoth As Boolean = True
1462 Private _exsearchUrl As Boolean = False
1463 Private _exuseRegex As Boolean = False
1464 Private _excaseSensitive As Boolean = False
1465 Private _moveFrom As Boolean = False
1466 Private _setMark As Boolean = True
1468 Public Sub New(ByVal NameFilter As String, _
1469 ByVal BodyFilter As List(Of String), _
1470 ByVal SearchBoth As Boolean, _
1471 ByVal SearchUrl As Boolean, _
1472 ByVal CaseSensitive As Boolean, _
1473 ByVal UseRegex As Boolean, _
1474 ByVal ParentTab As String, _
1475 ByVal ExNameFilter As String, _
1476 ByVal ExBodyFilter As List(Of String), _
1477 ByVal ExSearchBoth As Boolean, _
1478 ByVal ExSearchUrl As Boolean, _
1479 ByVal ExUseRegex As Boolean, _
1480 ByVal ExCaseSensitive As Boolean, _
1481 ByVal MoveFrom As Boolean, _
1482 ByVal SetMark As Boolean)
1485 _searchBoth = SearchBoth
1486 _searchUrl = SearchUrl
1487 _caseSensitive = CaseSensitive
1488 _useRegex = UseRegex
1489 _exname = ExNameFilter
1490 _exbody = ExBodyFilter
1491 _exsearchBoth = ExSearchBoth
1492 _exsearchUrl = ExSearchUrl
1493 _exuseRegex = ExUseRegex
1494 _excaseSensitive = ExCaseSensitive
1495 _moveFrom = MoveFrom
1500 Dim rgx As New Regex(_name)
1501 Catch ex As Exception
1502 Throw New Exception(My.Resources.ButtonOK_ClickText3 + ex.Message)
1505 For Each bs As String In _body
1507 Dim rgx As New Regex(bs)
1508 Catch ex As Exception
1509 Throw New Exception(My.Resources.ButtonOK_ClickText3 + ex.Message)
1516 Dim rgx As New Regex(_exname)
1517 Catch ex As Exception
1518 Throw New Exception(My.Resources.ButtonOK_ClickText3 + ex.Message)
1521 For Each bs As String In _exbody
1523 Dim rgx As New Regex(bs)
1524 Catch ex As Exception
1525 Throw New Exception(My.Resources.ButtonOK_ClickText3 + ex.Message)
1537 Private Function MakeSummary() As String
1538 Dim fs As New System.Text.StringBuilder()
1539 If _name <> "" OrElse _body.Count > 0 Then
1542 fs.AppendFormat(My.Resources.SetFiltersText1, _name)
1544 fs.Append(My.Resources.SetFiltersText2)
1547 If _body.Count > 0 Then
1548 fs.Append(My.Resources.SetFiltersText3)
1549 For Each bf As String In _body
1554 fs.Append(My.Resources.SetFiltersText4)
1558 fs.Append(My.Resources.SetFiltersText5)
1560 fs.Append(My.Resources.SetFiltersText6)
1563 fs.Append(My.Resources.SetFiltersText7)
1566 fs.Append(My.Resources.SetFiltersText8)
1568 If _caseSensitive Then
1569 fs.Append(My.Resources.SetFiltersText13)
1572 ' fs.Append(My.Resources.SetFiltersText9)
1573 'ElseIf _setMark Then
1574 ' fs.Append(My.Resources.SetFiltersText10)
1576 ' fs.Append(My.Resources.SetFiltersText11)
1581 If _exname <> "" OrElse _exbody.Count > 0 Then
1583 fs.Append(My.Resources.SetFiltersText12)
1584 If _exsearchBoth Then
1585 If _exname <> "" Then
1586 fs.AppendFormat(My.Resources.SetFiltersText1, _exname)
1588 fs.Append(My.Resources.SetFiltersText2)
1591 If _exbody.Count > 0 Then
1592 fs.Append(My.Resources.SetFiltersText3)
1593 For Each bf As String In _exbody
1598 fs.Append(My.Resources.SetFiltersText4)
1601 If _exsearchBoth Then
1602 fs.Append(My.Resources.SetFiltersText5)
1604 fs.Append(My.Resources.SetFiltersText6)
1607 fs.Append(My.Resources.SetFiltersText7)
1609 If _exsearchUrl Then
1610 fs.Append(My.Resources.SetFiltersText8)
1612 If _excaseSensitive Then
1613 fs.Append(My.Resources.SetFiltersText13)
1621 fs.Append(My.Resources.SetFiltersText9)
1623 fs.Append(My.Resources.SetFiltersText11)
1625 If Not _moveFrom AndAlso _setMark Then
1626 fs.Append(My.Resources.SetFiltersText10)
1627 ElseIf Not _moveFrom Then
1633 Return fs.ToString()
1636 Public Property NameFilter() As String
1640 Set(ByVal value As String)
1645 Public Property ExNameFilter() As String
1649 Set(ByVal value As String)
1654 <Xml.Serialization.XmlIgnore()> _
1655 Public Property BodyFilter() As List(Of String)
1659 Set(ByVal value As List(Of String))
1664 Public Property BodyFilterArray() As String()
1666 Return _body.ToArray
1668 Set(ByVal value As String())
1669 _body = New List(Of String)
1670 For Each filter As String In value
1676 <Xml.Serialization.XmlIgnore()> _
1677 Public Property ExBodyFilter() As List(Of String)
1681 Set(ByVal value As List(Of String))
1686 Public Property ExBodyFilterArray() As String()
1688 Return _exbody.ToArray
1690 Set(ByVal value As String())
1691 _exbody = New List(Of String)
1692 For Each filter As String In value
1698 Public Property SearchBoth() As Boolean
1702 Set(ByVal value As Boolean)
1707 Public Property ExSearchBoth() As Boolean
1709 Return _exsearchBoth
1711 Set(ByVal value As Boolean)
1712 _exsearchBoth = value
1716 Public Property MoveFrom() As Boolean
1720 Set(ByVal value As Boolean)
1725 Public Property SetMark() As Boolean
1729 Set(ByVal value As Boolean)
1734 Public Property SearchUrl() As Boolean
1738 Set(ByVal value As Boolean)
1743 Public Property ExSearchUrl() As Boolean
1747 Set(ByVal value As Boolean)
1748 _exsearchUrl = value
1752 Public Property CaseSensitive() As Boolean
1754 Return _caseSensitive
1756 Set(ByVal value As Boolean)
1757 _caseSensitive = value
1761 Public Property ExCaseSensitive() As Boolean
1763 Return _excaseSensitive
1765 Set(ByVal value As Boolean)
1766 _excaseSensitive = value
1770 Public Property UseRegex() As Boolean
1774 Set(ByVal value As Boolean)
1779 Public Property ExUseRegex() As Boolean
1783 Set(ByVal value As Boolean)
1788 Public Overrides Function ToString() As String
1789 Return MakeSummary()
1792 Public Function IsHit(ByVal Name As String, ByVal Body As String, ByVal OrgData As String) As HITRESULT
1793 Dim bHit As Boolean = True
1801 Dim compOpt As System.StringComparison
1802 Dim rgOpt As System.Text.RegularExpressions.RegexOptions
1803 If _caseSensitive Then
1804 compOpt = StringComparison.Ordinal
1805 rgOpt = RegexOptions.None
1807 compOpt = StringComparison.OrdinalIgnoreCase
1808 rgOpt = RegexOptions.IgnoreCase
1811 If _name = "" OrElse _
1812 Name.Equals(_name, compOpt) OrElse _
1813 (_useRegex AndAlso Regex.IsMatch(Name, _name, rgOpt)) Then
1814 For Each fs As String In _body
1816 If Regex.IsMatch(tBody, fs, rgOpt) = False Then bHit = False
1818 If _caseSensitive Then
1819 If tBody.Contains(fs) = False Then bHit = False
1821 If tBody.ToLower().Contains(fs.ToLower()) = False Then bHit = False
1824 If Not bHit Then Exit For
1830 For Each fs As String In _body
1832 If Not (Regex.IsMatch(Name, fs, rgOpt) OrElse _
1833 Regex.IsMatch(tBody, fs, rgOpt)) Then bHit = False
1835 If _caseSensitive Then
1836 If Not (Name.Contains(fs) OrElse _
1837 tBody.Contains(fs)) Then bHit = False
1839 If Not (Name.ToLower().Contains(fs.ToLower()) OrElse _
1840 tBody.ToLower().Contains(fs.ToLower())) Then bHit = False
1843 If Not bHit Then Exit For
1848 Dim exFlag As Boolean = False
1849 'If _name = "" AndAlso _body.Count = 0 Then
1853 If _exname <> "" OrElse _exbody.Count > 0 Then
1854 If _excaseSensitive Then
1855 compOpt = StringComparison.Ordinal
1856 rgOpt = RegexOptions.None
1858 compOpt = StringComparison.OrdinalIgnoreCase
1859 rgOpt = RegexOptions.IgnoreCase
1861 If _exsearchBoth Then
1862 If _exname = "" OrElse Name.Equals(_exname, compOpt) OrElse _
1863 (_exuseRegex AndAlso Regex.IsMatch(Name, _exname, rgOpt)) Then
1864 If _exbody.Count > 0 Then
1865 For Each fs As String In _exbody
1867 If Regex.IsMatch(tBody, fs, rgOpt) Then exFlag = True
1869 If _excaseSensitive Then
1870 If tBody.Contains(fs) Then exFlag = True
1872 If tBody.ToLower().Contains(fs.ToLower()) Then exFlag = True
1875 If exFlag Then Exit For
1882 For Each fs As String In _exbody
1884 If Regex.IsMatch(Name, fs, rgOpt) OrElse _
1885 Regex.IsMatch(tBody, fs, rgOpt) Then exFlag = True
1887 If _excaseSensitive Then
1888 If Name.Contains(fs) OrElse _
1889 tBody.Contains(fs) Then exFlag = True
1891 If Name.ToLower().Contains(fs.ToLower()) OrElse _
1892 tBody.ToLower().Contains(fs.ToLower()) Then exFlag = True
1895 If exFlag Then Exit For
1900 If _name = "" AndAlso _body.Count = 0 Then
1905 'If _setMark Then Return HITRESULT.CopyAndMark
1907 Return HITRESULT.Move
1910 Return HITRESULT.CopyAndMark
1912 Return HITRESULT.Copy
1914 'Return HITRESULT.Copy
1916 Return HITRESULT.Exclude
1920 Return HITRESULT.Exclude
1922 Return HITRESULT.None
1926 Return HITRESULT.None
1930 Public Overloads Function Equals(ByVal other As FiltersClass) As Boolean _
1931 Implements System.IEquatable(Of Tween.FiltersClass).Equals
1933 If Me.BodyFilter.Count <> other.BodyFilter.Count Then Return False
1934 If Me.ExBodyFilter.Count <> other.ExBodyFilter.Count Then Return False
1935 For i As Integer = 0 To Me.BodyFilter.Count - 1
1936 If Me.BodyFilter(i) <> other.BodyFilter(i) Then Return False
1938 For i As Integer = 0 To Me.ExBodyFilter.Count - 1
1939 If Me.ExBodyFilter(i) <> other.ExBodyFilter(i) Then Return False
1942 Return (Me.MoveFrom = other.MoveFrom) And _
1943 (Me.SetMark = other.SetMark) And _
1944 (Me.NameFilter = other.NameFilter) And _
1945 (Me.SearchBoth = other.SearchBoth) And _
1946 (Me.SearchUrl = other.SearchUrl) And _
1947 (Me.UseRegex = other.UseRegex) And _
1948 (Me.ExNameFilter = other.ExNameFilter) And _
1949 (Me.ExSearchBoth = other.ExSearchBoth) And _
1950 (Me.ExSearchUrl = other.ExSearchUrl) And _
1951 (Me.ExUseRegex = other.ExUseRegex)
1954 Public Overrides Function Equals(ByVal obj As Object) As Boolean
1955 If (obj Is Nothing) OrElse Not (Me.GetType() Is obj.GetType()) Then Return False
1956 Return Me.Equals(CType(obj, FiltersClass))
1959 Public Overrides Function GetHashCode() As Integer
1960 Return Me.MoveFrom.GetHashCode Xor _
1961 Me.SetMark.GetHashCode Xor _
1962 Me.BodyFilter.GetHashCode Xor _
1963 Me.NameFilter.GetHashCode Xor _
1964 Me.SearchBoth.GetHashCode Xor _
1965 Me.SearchUrl.GetHashCode Xor _
1966 Me.UseRegex.GetHashCode Xor _
1967 Me.ExBodyFilter.GetHashCode Xor _
1968 Me.ExNameFilter.GetHashCode Xor _
1969 Me.ExSearchBoth.GetHashCode Xor _
1970 Me.ExSearchUrl.GetHashCode Xor _
1971 Me.ExUseRegex.GetHashCode
1976 Public NotInheritable Class IdComparerClass
1977 Implements IComparer(Of Long)
1982 Public Enum ComparerMode
1990 Private _order As SortOrder
1991 Private _mode As ComparerMode
1992 Private _statuses As TabInformations
1993 Private _CmpMethod As Comparison(Of Long)
1996 ''' 昇順か降順か Setの際は同時に比較関数の切り替えを行う
1998 Public Property Order() As SortOrder
2002 Set(ByVal Value As SortOrder)
2004 SetCmpMethod(_mode, _order)
2009 ''' 並び替えの方法 Setの際は同時に比較関数の切り替えを行う
2011 Public Property Mode() As ComparerMode
2015 Set(ByVal Value As ComparerMode)
2017 SetCmpMethod(_mode, _order)
2022 ''' ListViewItemComparerクラスのコンストラクタ(引数付は未使用)
2024 ''' <param name="col">並び替える列番号</param>
2025 ''' <param name="ord">昇順か降順か</param>
2026 ''' <param name="cmod">並び替えの方法</param>
2027 Public Sub New(ByVal ord As SortOrder, ByVal SortMode As ComparerMode)
2030 SetCmpMethod(_mode, _order)
2033 Public Sub New(ByVal TabInf As TabInformations)
2034 _order = SortOrder.Ascending
2035 _mode = ComparerMode.Id
2037 SetCmpMethod(_mode, _order)
2040 ' 指定したソートモードとソートオーダーに従い使用する比較関数のアドレスを返す
2041 Public Overloads ReadOnly Property CmpMethod(ByVal _sortmode As ComparerMode, ByVal _sortorder As SortOrder) As Comparison(Of Long)
2043 Dim _method As Comparison(Of Long) = Nothing
2044 If _sortorder = SortOrder.Ascending Then
2046 Select Case _sortmode
2047 Case ComparerMode.Data
2048 _method = AddressOf Compare_ModeData_Ascending
2049 Case ComparerMode.Id
2050 _method = AddressOf Compare_ModeId_Ascending
2051 Case ComparerMode.Name
2052 _method = AddressOf Compare_ModeName_Ascending
2053 Case ComparerMode.Nickname
2054 _method = AddressOf Compare_ModeNickName_Ascending
2055 Case ComparerMode.Source
2056 _method = AddressOf Compare_ModeSource_Ascending
2060 Select Case _sortmode
2061 Case ComparerMode.Data
2062 _method = AddressOf Compare_ModeData_Descending
2063 Case ComparerMode.Id
2064 _method = AddressOf Compare_ModeId_Descending
2065 Case ComparerMode.Name
2066 _method = AddressOf Compare_ModeName_Descending
2067 Case ComparerMode.Nickname
2068 _method = AddressOf Compare_ModeNickName_Descending
2069 Case ComparerMode.Source
2070 _method = AddressOf Compare_ModeSource_Descending
2077 ' ソートモードとソートオーダーに従い使用する比較関数のアドレスを返す
2078 ' (overload 現在の使用中の比較関数のアドレスを返す)
2079 Public Overloads ReadOnly Property CmpMethod() As Comparison(Of Long)
2085 ' ソートモードとソートオーダーに従い比較関数のアドレスを切り替え
2086 Private Sub SetCmpMethod(ByVal mode As ComparerMode, ByVal order As SortOrder)
2087 _CmpMethod = Me.CmpMethod(mode, order)
2090 'xがyより小さいときはマイナスの数、大きいときはプラスの数、
2091 '同じときは0を返す (こちらは未使用 一応比較関数群呼び出しの形のまま残しておく)
2092 Public Function Compare(ByVal x As Long, ByVal y As Long) _
2093 As Integer Implements IComparer(Of Long).Compare
2094 Return _CmpMethod(x, y)
2097 ' 比較用関数群 いずれもステータスIDの順序を考慮する
2098 ' 注:ID比較でCTypeを使用しているが、abs(x-y)がInteger(Int32)に収まらないことはあり得ないのでこれでよい
2100 Public Function Compare_ModeData_Ascending(ByVal x As Long, ByVal y As Long) As Integer
2101 Dim result As Integer = String.Compare(_statuses.Item(x).Data, _statuses.Item(y).Data)
2102 If result = 0 Then result = x.CompareTo(y)
2107 Public Function Compare_ModeData_Descending(ByVal x As Long, ByVal y As Long) As Integer
2108 Dim result As Integer = String.Compare(_statuses.Item(y).Data, _statuses.Item(x).Data)
2109 If result = 0 Then result = y.CompareTo(x)
2114 Public Function Compare_ModeId_Ascending(ByVal x As Long, ByVal y As Long) As Integer
2115 Return x.CompareTo(y)
2119 Public Function Compare_ModeId_Descending(ByVal x As Long, ByVal y As Long) As Integer
2120 Return y.CompareTo(x)
2124 Public Function Compare_ModeName_Ascending(ByVal x As Long, ByVal y As Long) As Integer
2125 Dim result As Integer = String.Compare(_statuses.Item(x).Name, _statuses.Item(y).Name)
2126 If result = 0 Then result = x.CompareTo(y)
2131 Public Function Compare_ModeName_Descending(ByVal x As Long, ByVal y As Long) As Integer
2132 Dim result As Integer = String.Compare(_statuses.Item(y).Name, _statuses.Item(x).Name)
2133 If result = 0 Then result = y.CompareTo(x)
2138 Public Function Compare_ModeNickName_Ascending(ByVal x As Long, ByVal y As Long) As Integer
2139 Dim result As Integer = String.Compare(_statuses.Item(x).Nickname, _statuses.Item(y).Nickname)
2140 If result = 0 Then result = x.CompareTo(y)
2145 Public Function Compare_ModeNickName_Descending(ByVal x As Long, ByVal y As Long) As Integer
2146 Dim result As Integer = String.Compare(_statuses.Item(y).Nickname, _statuses.Item(x).Nickname)
2147 If result = 0 Then result = y.CompareTo(x)
2152 Public Function Compare_ModeSource_Ascending(ByVal x As Long, ByVal y As Long) As Integer
2153 Dim result As Integer = String.Compare(_statuses.Item(x).Source, _statuses.Item(y).Source)
2154 If result = 0 Then result = x.CompareTo(y)
2159 Public Function Compare_ModeSource_Descending(ByVal x As Long, ByVal y As Long) As Integer
2160 Dim result As Integer = String.Compare(_statuses.Item(y).Source, _statuses.Item(x).Source)
2161 If result = 0 Then result = y.CompareTo(x)