1 ' Tween - Client of Twitter
2 ' Copyright (c) 2007-2011 kiri_feather (@kiri_feather) <kiri.feather@gmail.com>
3 ' (c) 2008-2011 Moz (@syo68k)
4 ' (c) 2008-2011 takeshik (@takeshik) <http://www.takeshik.org/>
5 ' (c) 2010-2011 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
6 ' (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
9 ' This file is part of Tween.
11 ' This program is free software; you can redistribute it and/or modify it
12 ' under the terms of the GNU General Public License as published by the Free
13 ' Software Foundation; either version 3 of the License, or (at your option)
16 ' This program is distributed in the hope that it will be useful, but
17 ' WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 ' or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 ' You should have received a copy of the GNU General Public License along
22 ' with this program. If not, see <http://www.gnu.org/licenses/>, or write to
23 ' the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
24 ' Boston, MA 02110-1301, USA.
26 Imports System.Collections.Generic
27 Imports System.Collections.ObjectModel
28 Imports System.Linq.Expressions
29 Imports Tween.TweenCustomControl
30 Imports System.Text.RegularExpressions
31 Imports System.Web.HttpUtility
34 Imports System.Linq.Expressions.DynamicExpression
36 Public NotInheritable Class PostClass
38 Private _Nick As String
39 Private _textFromApi As String
40 Private _ImageUrl As String
41 Private _screenName As String
42 Private _createdAt As Date
43 Private _statusId As Long
44 Private _IsFav As Boolean
45 Private _text As String
46 Private _IsRead As Boolean
47 Private _IsReply As Boolean
48 Private _IsExcludeReply As Boolean
49 Private _IsProtect As Boolean
50 Private _IsOWL As Boolean
51 Private _IsMark As Boolean
52 Private _InReplyToUser As String
53 Private _InReplyToStatusId As Long
54 Private _Source As String
55 Private _SourceHtml As String
56 Private _ReplyToList As New List(Of String)
57 Private _IsMe As Boolean
58 Private _IsDm As Boolean
59 Private _statuses As Statuses = Statuses.None
60 Private _UserId As Long
61 Private _FilterHit As Boolean
62 Private _RetweetedBy As String = ""
63 Private _RetweetedId As Long = 0
64 Private _SearchTabName As String = ""
65 Private _IsDeleted As Boolean = False
66 Private _InReplyToUserId As Long = 0
77 Public Sub New(ByVal Nickname As String, _
78 ByVal textFromApi As String, _
79 ByVal text As String, _
80 ByVal ImageUrl As String, _
81 ByVal screenName As String, _
82 ByVal createdAt As Date, _
83 ByVal statusId As Long, _
84 ByVal IsFav As Boolean, _
85 ByVal IsRead As Boolean, _
86 ByVal IsReply As Boolean, _
87 ByVal IsExcludeReply As Boolean, _
88 ByVal IsProtect As Boolean, _
89 ByVal IsOwl As Boolean, _
90 ByVal IsMark As Boolean, _
91 ByVal InReplyToUser As String, _
92 ByVal InReplyToStatusId As Long, _
93 ByVal Source As String, _
94 ByVal SourceHtml As String, _
95 ByVal ReplyToList As List(Of String), _
96 ByVal IsMe As Boolean, _
97 ByVal IsDm As Boolean, _
98 ByVal userId As Long, _
99 ByVal FilterHit As Boolean, _
100 ByVal RetweetedBy As String, _
101 ByVal RetweetedId As Long)
103 _textFromApi = textFromApi
105 _screenName = screenName
106 _createdAt = createdAt
112 _IsExcludeReply = IsExcludeReply
113 _IsProtect = IsProtect
116 _InReplyToUser = InReplyToUser
117 _InReplyToStatusId = InReplyToStatusId
119 _SourceHtml = SourceHtml
120 _ReplyToList = ReplyToList
124 _FilterHit = FilterHit
125 _RetweetedBy = RetweetedBy
126 _RetweetedId = RetweetedId
132 Public Property Nickname() As String
136 Set(ByVal value As String)
140 Public Property TextFromApi() As String
144 Set(ByVal value As String)
148 Public Property ImageUrl() As String
152 Set(ByVal value As String)
156 Public Property ScreenName() As String
160 Set(ByVal value As String)
164 Public Property CreatedAt() As Date
168 Set(ByVal value As Date)
172 Public Property StatusId() As Long
176 Set(ByVal value As Long)
180 Public Property IsFav() As Boolean
182 If Me.RetweetedId > 0 AndAlso TabInformations.GetInstance.RetweetSource(Me.RetweetedId) IsNot Nothing Then
183 Return TabInformations.GetInstance.RetweetSource(Me.RetweetedId).IsFav
188 Set(ByVal value As Boolean)
190 If Me.RetweetedId > 0 AndAlso TabInformations.GetInstance.RetweetSource(Me.RetweetedId) IsNot Nothing Then
191 TabInformations.GetInstance.RetweetSource(Me.RetweetedId).IsFav = value
195 Public Property Text() As String
199 Set(ByVal value As String)
203 Public Property IsRead() As Boolean
207 Set(ByVal value As Boolean)
209 _statuses = _statuses Or Statuses.Read
211 _statuses = _statuses And Not Statuses.Read
216 Public Property IsReply() As Boolean
220 Set(ByVal value As Boolean)
224 Public Property IsExcludeReply() As Boolean
226 Return _IsExcludeReply
228 Set(ByVal value As Boolean)
229 _IsExcludeReply = value
232 Public Property IsProtect() As Boolean
236 Set(ByVal value As Boolean)
238 _statuses = _statuses Or Statuses.Protect
240 _statuses = _statuses And Not Statuses.Protect
245 Public Property IsOwl() As Boolean
249 Set(ByVal value As Boolean)
253 Public Property IsMark() As Boolean
257 Set(ByVal value As Boolean)
259 _statuses = _statuses Or Statuses.Mark
261 _statuses = _statuses And Not Statuses.Mark
266 Public Property InReplyToUser() As String
268 Return _InReplyToUser
270 Set(ByVal value As String)
271 _InReplyToUser = value
274 Public Property InReplyToStatusId() As Long
276 Return _InReplyToStatusId
278 Set(ByVal value As Long)
279 _InReplyToStatusId = value
283 Public Property InReplyToUserId() As Long
285 Return _InReplyToUserId
287 Set(ByVal value As Long)
288 _InReplyToUserId = value
291 Public Property Source() As String
295 Set(ByVal value As String)
299 Public Property SourceHtml() As String
303 Set(ByVal value As String)
307 Public Property ReplyToList() As List(Of String)
311 Set(ByVal value As List(Of String))
315 Public Property IsMe() As Boolean
319 Set(ByVal value As Boolean)
323 Public Property IsDm() As Boolean
327 Set(ByVal value As Boolean)
331 'Public ReadOnly Property StatusIndex() As Integer
336 Public Property UserId() As Long
340 Set(ByVal value As Long)
344 Public Property FilterHit() As Boolean
348 Set(ByVal value As Boolean)
352 Public Property RetweetedBy() As String
356 Set(ByVal value As String)
360 Public Property RetweetedId() As Long
364 Set(ByVal value As Long)
368 Public Property RelTabName() As String
370 Return _SearchTabName
372 Set(ByVal value As String)
373 _SearchTabName = value
376 Public Property IsDeleted As Boolean
380 Set(ByVal value As Boolean)
382 Me.InReplyToStatusId = 0
383 Me.InReplyToUser = ""
384 Me.InReplyToUserId = 0
386 Me.ReplyToList = New List(Of String)
392 Public Property FavoritedCount As Integer
394 Public Function Copy() As PostClass
395 Dim post As PostClass = DirectCast(Me.Clone, PostClass)
396 post.ReplyToList = New List(Of String)(Me.ReplyToList)
400 Public Overrides Function Equals(ByVal obj As Object) As Boolean
401 If (obj Is Nothing) OrElse Not (Me.GetType() Is obj.GetType()) Then Return False
402 Return Me.Equals(CType(obj, PostClass))
405 Public Overloads Function Equals(ByVal other As PostClass) As Boolean
406 If other Is Nothing Then Return False
407 Return (Me.Nickname = other.Nickname) AndAlso
408 (Me.TextFromApi = other.TextFromApi) AndAlso
409 (Me.ImageUrl = other.ImageUrl) AndAlso
410 (Me.ScreenName = other.ScreenName) AndAlso
411 (Me.CreatedAt = other.CreatedAt) AndAlso
412 (Me.StatusId = other.StatusId) AndAlso
413 (Me.IsFav = other.IsFav) AndAlso
414 (Me.Text = other.Text) AndAlso
415 (Me.IsRead = other.IsRead) AndAlso
416 (Me.IsReply = other.IsReply) AndAlso
417 (Me.IsExcludeReply = other.IsExcludeReply) AndAlso
418 (Me.IsProtect = other.IsProtect) AndAlso
419 (Me.IsOwl = other.IsOwl) AndAlso
420 (Me.IsMark = other.IsMark) AndAlso
421 (Me.InReplyToUser = other.InReplyToUser) AndAlso
422 (Me.InReplyToStatusId = other.InReplyToStatusId) AndAlso
423 (Me.Source = other.Source) AndAlso
424 (Me.SourceHtml = other.SourceHtml) AndAlso
425 (Me.ReplyToList.Equals(other.ReplyToList)) AndAlso
426 (Me.IsMe = other.IsMe) AndAlso
427 (Me.IsDm = other.IsDm) AndAlso
428 (Me.UserId = other.UserId) AndAlso
429 (Me.FilterHit = other.FilterHit) AndAlso
430 (Me.RetweetedBy = other.RetweetedBy) AndAlso
431 (Me.RetweetedId = other.RetweetedId) AndAlso
432 (Me.RelTabName = other.RelTabName) AndAlso
433 (Me.IsDeleted = other.IsDeleted) AndAlso
434 (Me.InReplyToUserId = other.InReplyToUserId)
437 #Region "IClonable.Clone"
438 Private Function Clone() As Object Implements ICloneable.Clone
439 Return Me.MemberwiseClone()
444 Public NotInheritable Class TabInformations
445 '個別タブの情報をDictionaryで保持
446 Private _sorter As IdComparerClass
447 Private _tabs As New Dictionary(Of String, TabClass)
448 Private _statuses As New Dictionary(Of Long, PostClass)
449 Private _addedIds As List(Of Long)
450 Private _deletedIds As New List(Of Long)
451 Private _retweets As New Dictionary(Of Long, PostClass)
452 Private _removedTab As New Stack(Of TabClass)
455 'AddPost(複数回) -> DistributePosts -> SubmitUpdate
458 Private _addCount As Integer
459 Private _soundFile As String
460 Private _notifyPosts As List(Of PostClass)
461 Private ReadOnly LockObj As New Object
462 Private ReadOnly LockUnread As New Object
464 Private Shared _instance As TabInformations = New TabInformations
467 Private _lists As New List(Of ListElement)
470 _sorter = New IdComparerClass()
473 Public Shared Function GetInstance() As TabInformations
474 Return _instance 'singleton
477 Public Property SubscribableLists() As List(Of ListElement)
481 Set(ByVal value As List(Of ListElement))
482 If value IsNot Nothing AndAlso value.Count > 0 Then
483 For Each tb As TabClass In Me.GetTabsByType(TabUsageType.Lists)
484 For Each list As ListElement In value
485 If tb.ListInfo.Id = list.Id Then
496 Public Sub AddTab(ByVal TabName As String, ByVal TabType As TabUsageType, ByVal List As ListElement)
497 _tabs.Add(TabName, New TabClass(TabName, TabType, List))
498 _tabs(TabName).Sorter.Mode = _sorter.Mode
499 _tabs(TabName).Sorter.Order = _sorter.Order
502 'Public Sub AddTab(ByVal TabName As String, ByVal Tab As TabClass)
503 ' _tabs.Add(TabName, Tab)
506 Public Sub RemoveTab(ByVal TabName As String)
508 If IsDefaultTab(TabName) Then Exit Sub '念のため
509 If Not _tabs(TabName).IsInnerStorageTabType Then
510 Dim homeTab As TabClass = GetTabByType(TabUsageType.Home)
511 Dim dmName As String = GetTabByType(TabUsageType.DirectMessage).TabName
513 For idx As Integer = 0 To _tabs(TabName).AllCount - 1
514 Dim exist As Boolean = False
515 Dim Id As Long = _tabs(TabName).GetId(idx)
516 If Id < 0 Then Continue For
517 For Each key As String In _tabs.Keys
518 If Not key = TabName AndAlso key <> dmName Then
519 If _tabs(key).Contains(Id) Then
525 If Not exist Then homeTab.Add(Id, _statuses(Id).IsRead, False)
528 _removedTab.Push(_tabs(TabName))
529 _tabs.Remove(TabName)
533 Public RemovedTab As Stack(Of TabClass) = _removedTab
535 Public Function ContainsTab(ByVal TabText As String) As Boolean
536 Return _tabs.ContainsKey(TabText)
539 Public Function ContainsTab(ByVal ts As TabClass) As Boolean
540 Return _tabs.ContainsValue(ts)
543 Public Property Tabs() As Dictionary(Of String, TabClass)
547 Set(ByVal value As Dictionary(Of String, TabClass))
552 Public ReadOnly Property KeysTab() As Collections.Generic.Dictionary(Of String, TabClass).KeyCollection
558 Public Sub SortPosts()
559 For Each key As String In _tabs.Keys
564 Public Property SortOrder() As SortOrder
568 Set(ByVal value As SortOrder)
569 _sorter.Order = value
570 For Each key As String In _tabs.Keys
571 _tabs(key).Sorter.Order = value
576 Public Property SortMode() As IdComparerClass.ComparerMode
580 Set(ByVal value As IdComparerClass.ComparerMode)
582 For Each key As String In _tabs.Keys
583 _tabs(key).Sorter.Mode = value
588 Public Function ToggleSortOrder(ByVal SortMode As IdComparerClass.ComparerMode) As Windows.Forms.SortOrder
589 If _sorter.Mode = SortMode Then
590 If _sorter.Order = Windows.Forms.SortOrder.Ascending Then
591 _sorter.Order = Windows.Forms.SortOrder.Descending
593 _sorter.Order = Windows.Forms.SortOrder.Ascending
595 For Each key As String In _tabs.Keys
596 _tabs(key).Sorter.Order = _sorter.Order
599 _sorter.Mode = SortMode
600 _sorter.Order = Windows.Forms.SortOrder.Ascending
601 For Each key As String In _tabs.Keys
602 _tabs(key).Sorter.Mode = SortMode
603 _tabs(key).Sorter.Order = Windows.Forms.SortOrder.Ascending
610 Public ReadOnly Property RetweetSource(ByVal Id As Long) As PostClass
612 If _retweets.ContainsKey(Id) Then
620 Public Sub RemoveFavPost(ByVal Id As Long)
622 Dim post As PostClass = Nothing
623 Dim tab As TabClass = Me.GetTabByType(TabUsageType.Favorites)
624 Dim tn As String = tab.TabName
625 If _statuses.ContainsKey(Id) Then
628 Dim tType As TabUsageType = tab.TabType
629 If tab.Contains(Id) Then
630 If tab.UnreadManage AndAlso Not post.IsRead Then '未読管理
633 Me.SetNextUnreadId(Id, tab)
638 'FavタブからRetweet発言を削除する場合は、他の同一参照Retweetも削除
639 If tType = TabUsageType.Favorites AndAlso post.RetweetedId > 0 Then
640 For i As Integer = 0 To tab.AllCount - 1
641 Dim rPost As PostClass = Nothing
643 rPost = Me.Item(tn, i)
644 Catch ex As ArgumentOutOfRangeException
647 If rPost.RetweetedId > 0 AndAlso rPost.RetweetedId = post.RetweetedId Then
648 If tab.UnreadManage AndAlso Not rPost.IsRead Then '未読管理
651 Me.SetNextUnreadId(rPost.StatusId, tab)
654 tab.Remove(rPost.StatusId)
659 ''TabType=PublicSearchの場合(Postの保存先がTabClass内)
660 'If tab.Contains(StatusId) AndAlso _
661 ' (tab.TabType = TabUsageType.PublicSearch OrElse tab.TabType = TabUsageType.DirectMessage) Then
662 ' post = tab.Posts(StatusId)
663 ' If tab.UnreadManage AndAlso Not post.IsRead Then '未読管理
664 ' SyncLock LockUnread
665 ' tab.UnreadCount -= 1
666 ' Me.SetNextUnreadId(StatusId, tab)
669 ' tab.Remove(StatusId)
674 Public Sub RemovePostReserve(ByVal id As Long)
676 Me._deletedIds.Add(id)
677 Me.DeletePost(id) 'UI選択行がずれるため、RemovePostは使用しない
681 Public Sub RemovePost(ByVal Id As Long)
683 Dim post As PostClass = Nothing
684 If _statuses.ContainsKey(Id) Then
687 For Each key As String In _tabs.Keys
688 Dim tab As TabClass = _tabs(key)
689 If tab.Contains(Id) Then
690 If Not tab.IsInnerStorageTabType Then
691 If tab.UnreadManage AndAlso Not post.IsRead Then '未読管理
694 Me.SetNextUnreadId(Id, tab)
697 Else '未読数がずれる可能性があるためtab.Postsの未読も確認する
698 If tab.UnreadManage AndAlso Not tab.Posts(Id).IsRead Then '未読管理
701 Me.SetNextUnreadId(Id, tab)
713 Private Sub DeletePost(ByVal Id As Long)
715 Dim post As PostClass = Nothing
716 If _statuses.ContainsKey(Id) Then
718 post.IsDeleted = True
720 For Each tb As TabClass In Me.GetTabsInnerStorageType
721 If tb.Contains(Id) Then
723 post.IsDeleted = True
729 Public Function GetOldestUnreadIndex(ByVal TabName As String) As Integer
730 Dim tb As TabClass = _tabs(TabName)
731 If tb.OldestUnreadId > -1 AndAlso _
732 tb.Contains(tb.OldestUnreadId) AndAlso _
733 tb.UnreadCount > 0 Then
735 Dim isRead As Boolean
736 If Not tb.IsInnerStorageTabType Then
737 isRead = _statuses(tb.OldestUnreadId).IsRead
739 isRead = tb.Posts(tb.OldestUnreadId).IsRead
744 Me.SetNextUnreadId(-1, tb) '頭から探索
746 If tb.OldestUnreadId = -1 Then
749 Return tb.IndexOf(tb.OldestUnreadId)
752 Return tb.IndexOf(tb.OldestUnreadId) '最短経路
755 '一見未読なさそうだが、未読カウントはあるので探索
756 'If tb.UnreadCount > 0 Then
757 If Not (tb.UnreadManage AndAlso AppendSettingDialog.Instance.UnreadManage) Then Return -1
759 Me.SetNextUnreadId(-1, tb)
761 If tb.OldestUnreadId = -1 Then
764 Return tb.IndexOf(tb.OldestUnreadId)
772 Private Sub SetNextUnreadId(ByVal CurrentId As Long, ByVal Tab As TabClass)
773 'CurrentID:今既読にしたID(OldestIDの可能性あり)
774 '最古未読が設定されていて、既読の場合(1発言以上存在)
776 Dim posts As Dictionary(Of Long, PostClass)
777 If Not Tab.IsInnerStorageTabType Then
782 If Tab.OldestUnreadId > -1 AndAlso _
783 posts.ContainsKey(Tab.OldestUnreadId) AndAlso _
784 posts.Item(Tab.OldestUnreadId).IsRead AndAlso _
785 _sorter.Mode = IdComparerClass.ComparerMode.Id Then '次の未読探索
786 If Tab.UnreadCount = 0 Then
788 Tab.OldestUnreadId = -1
789 ElseIf Tab.OldestUnreadId = CurrentId AndAlso CurrentId > -1 Then
790 '最古IDを既読にしたタイミング→次のIDから続けて探索
791 Dim idx As Integer = Tab.IndexOf(CurrentId)
794 FindUnreadId(idx, Tab)
797 FindUnreadId(-1, Tab)
801 FindUnreadId(-1, Tab)
805 FindUnreadId(-1, Tab)
807 Catch ex As Generic.KeyNotFoundException
809 FindUnreadId(-1, Tab)
813 Private Sub FindUnreadId(ByVal StartIdx As Integer, ByVal Tab As TabClass)
814 If Tab.AllCount = 0 Then
815 Tab.OldestUnreadId = -1
819 Dim toIdx As Integer = 0
820 Dim stp As Integer = 1
821 Tab.OldestUnreadId = -1
822 If _sorter.Order = Windows.Forms.SortOrder.Ascending Then
823 If StartIdx = -1 Then
827 If StartIdx > Tab.AllCount - 1 Then StartIdx = Tab.AllCount - 1 '念のため
829 toIdx = Tab.AllCount - 1
830 If toIdx < 0 Then toIdx = 0 '念のため
833 If StartIdx = -1 Then
834 StartIdx = Tab.AllCount - 1
838 If StartIdx < 0 Then StartIdx = 0 '念のため
842 If Not Tab.IsInnerStorageTabType Then
843 For i As Integer = StartIdx To toIdx Step stp
844 If Not _statuses(Tab.GetId(i)).IsRead Then
845 Tab.OldestUnreadId = Tab.GetId(i)
850 For i As Integer = StartIdx To toIdx Step stp
851 If Not Tab.Posts(Tab.GetId(i)).IsRead Then
852 Tab.OldestUnreadId = Tab.GetId(i)
859 Public Function DistributePosts() As Integer
862 'If _addedIds Is Nothing Then Return 0
863 'If _addedIds.Count = 0 Then Return 0
865 If _addedIds Is Nothing Then _addedIds = New List(Of Long)
866 If _notifyPosts Is Nothing Then _notifyPosts = New List(Of PostClass)
867 Me.Distribute() 'タブに仮振分
868 Dim retCnt As Integer = _addedIds.Count
871 _addedIds = Nothing '後始末
876 Public Function SubmitUpdate(ByRef soundFile As String,
877 ByRef notifyPosts As PostClass(),
878 ByRef isMentionIncluded As Boolean,
879 ByRef isDeletePost As Boolean,
880 ByVal isUserStream As Boolean) As Integer
883 If _notifyPosts Is Nothing Then
885 notifyPosts = Nothing
889 For Each tb As TabClass In _tabs.Values
890 If tb.IsInnerStorageTabType Then
891 _addCount += tb.GetTemporaryCount
893 tb.AddSubmit(isMentionIncluded) '振分確定(各タブに反映)
895 ''UserStreamで反映間隔10秒以下だったら、30秒ごとにソートする
897 'Static lastSort As DateTime = Now
898 'If AppendSettingDialog.Instance.UserstreamPeriodInt < 10 AndAlso isUserStream Then
899 ' If Now.Subtract(lastSort) > TimeSpan.FromSeconds(30) Then
901 ' isUserStream = False
904 ' isUserStream = False
906 If Not isUserStream OrElse Me.SortMode <> IdComparerClass.ComparerMode.Id Then
910 isDeletePost = Me._deletedIds.Count > 0
911 For Each id As Long In Me._deletedIds
912 'Me.DeletePost(StatusId)
915 Me._deletedIds.Clear()
918 soundFile = _soundFile
920 notifyPosts = _notifyPosts.ToArray()
922 _notifyPosts = Nothing
923 Dim retCnt As Integer = _addCount
925 Return retCnt '件数(EndUpdateの戻り値と同じ)
929 Private Sub Distribute()
930 '各タブのフィルターと照合。合致したらタブにID追加
931 '通知メッセージ用に、表示必要な発言リストと再生サウンドを返す
932 'notifyPosts = New List(Of PostClass)
933 Dim homeTab As TabClass = GetTabByType(TabUsageType.Home)
934 Dim replyTab As TabClass = GetTabByType(TabUsageType.Mentions)
935 Dim dmTab As TabClass = GetTabByType(TabUsageType.DirectMessage)
936 Dim favTab As TabClass = GetTabByType(TabUsageType.Favorites)
937 For Each id As Long In _addedIds
938 Dim post As PostClass = _statuses(id)
939 Dim add As Boolean = False '通知リスト追加フラグ
940 Dim mv As Boolean = False '移動フラグ(Recent追加有無)
941 Dim rslt As HITRESULT = HITRESULT.None
942 post.IsExcludeReply = False
943 For Each tn As String In _tabs.Keys
944 rslt = _tabs(tn).AddFiltered(post)
945 If rslt <> HITRESULT.None AndAlso rslt <> HITRESULT.Exclude Then
946 If rslt = HITRESULT.CopyAndMark Then post.IsMark = True 'マークあり
947 If rslt = HITRESULT.Move Then
951 If _tabs(tn).Notify Then add = True '通知あり
952 If Not _tabs(tn).SoundFile = "" AndAlso _soundFile = "" Then
953 _soundFile = _tabs(tn).SoundFile 'wavファイル(未設定の場合のみ)
955 post.FilterHit = True
957 If rslt = HITRESULT.Exclude AndAlso _tabs(tn).TabType = TabUsageType.Mentions Then
958 post.IsExcludeReply = True
960 post.FilterHit = False
963 If Not mv Then '移動されなかったらRecentに追加
964 homeTab.Add(post.StatusId, post.IsRead, True)
965 If Not homeTab.SoundFile = "" AndAlso _soundFile = "" Then _soundFile = homeTab.SoundFile
966 If homeTab.Notify Then add = True
968 If post.IsReply AndAlso Not post.IsExcludeReply Then '除外ルール適用のないReplyならReplyタブに追加
969 replyTab.Add(post.StatusId, post.IsRead, True)
970 If Not replyTab.SoundFile = "" Then _soundFile = replyTab.SoundFile
971 If replyTab.Notify Then add = True
973 If post.IsFav Then 'Fav済み発言だったらFavoritesタブに追加
974 If favTab.Contains(post.StatusId) Then
979 favTab.Add(post.StatusId, post.IsRead, True)
980 If Not String.IsNullOrEmpty(favTab.SoundFile) AndAlso String.IsNullOrEmpty(_soundFile) Then _soundFile = favTab.SoundFile
981 If favTab.Notify Then add = True
984 If add Then _notifyPosts.Add(post)
986 For Each tb As TabClass In _tabs.Values
987 If tb.IsInnerStorageTabType Then
989 If tb.GetTemporaryCount > 0 Then
990 For Each post As PostClass In tb.GetTemporaryPosts
991 Dim exist As Boolean = False
992 For Each npost As PostClass In _notifyPosts
993 If npost.StatusId = post.StatusId Then
998 If Not exist Then _notifyPosts.Add(post)
1000 If tb.SoundFile <> "" Then
1001 If tb.TabType = TabUsageType.DirectMessage OrElse _soundFile = "" Then
1002 _soundFile = tb.SoundFile
1011 Public Sub AddPost(ByVal Item As PostClass)
1013 If Item.RelTabName = "" Then
1014 If Not Item.IsDm Then
1015 If _statuses.ContainsKey(Item.StatusId) Then
1017 If Item.RetweetedId = 0 Then
1018 _statuses.Item(Item.StatusId).IsFav = True
1023 Exit Sub '追加済みなら何もしない
1026 If Item.IsFav AndAlso Item.RetweetedId > 0 Then Item.IsFav = False
1027 _statuses.Add(Item.StatusId, Item)
1029 If Item.RetweetedId > 0 Then
1032 If Item.IsFav AndAlso _retweets.ContainsKey(Item.StatusId) Then
1033 Exit Sub 'Fav済みのRetweet元発言は追加しない
1035 If _addedIds Is Nothing Then _addedIds = New List(Of Long) 'タブ追加用IDコレクション準備
1036 _addedIds.Add(Item.StatusId)
1039 Dim tb As TabClass = Me.GetTabByType(TabUsageType.DirectMessage)
1040 If tb.Contains(Item.StatusId) Then Exit Sub
1041 tb.AddPostToInnerStorage(Item)
1046 If Me.Tabs.ContainsKey(Item.RelTabName) Then
1047 tb = Me.Tabs(Item.RelTabName)
1051 If tb Is Nothing Then Exit Sub
1052 If tb.Contains(Item.StatusId) Then Exit Sub
1053 'tb.Add(Item.StatusId, Item.IsRead, True)
1054 tb.AddPostToInnerStorage(Item)
1059 Private Sub AddRetweet(ByVal item As PostClass)
1060 If _retweets.ContainsKey(item.RetweetedId) Then Exit Sub
1075 item.IsExcludeReply, _
1079 item.InReplyToUser, _
1080 item.InReplyToStatusId, _
1094 Public Sub SetReadAllTab(ByVal Read As Boolean, ByVal TabName As String, ByVal Index As Integer)
1095 'Read:True=既読へ False=未読へ
1096 Dim tb As TabClass = _tabs(TabName)
1098 If tb.UnreadManage = False Then Exit Sub '未読管理していなければ終了
1100 Dim Id As Long = tb.GetId(Index)
1101 If Id < 0 Then Exit Sub
1102 Dim post As PostClass
1103 If Not tb.IsInnerStorageTabType Then
1104 post = _statuses(Id)
1109 If post.IsRead = Read Then Exit Sub '状態変更なければ終了
1116 Me.SetNextUnreadId(Id, tb) '次の未読セット
1117 '他タブの最古未読IDはタブ切り替え時に。
1118 If tb.IsInnerStorageTabType Then
1120 If _statuses.ContainsKey(Id) AndAlso Not _statuses(Id).IsRead Then
1121 For Each key As String In _tabs.Keys
1122 If _tabs(key).UnreadManage AndAlso _
1123 _tabs(key).Contains(Id) AndAlso _
1124 Not _tabs(key).IsInnerStorageTabType Then
1125 _tabs(key).UnreadCount -= 1
1126 If _tabs(key).OldestUnreadId = Id Then _tabs(key).OldestUnreadId = -1
1129 _statuses(Id).IsRead = True
1133 For Each key As String In _tabs.Keys
1134 If key <> TabName AndAlso _
1135 _tabs(key).UnreadManage AndAlso _
1136 _tabs(key).Contains(Id) AndAlso _
1137 Not _tabs(key).IsInnerStorageTabType Then
1138 _tabs(key).UnreadCount -= 1
1139 If _tabs(key).OldestUnreadId = Id Then _tabs(key).OldestUnreadId = -1
1144 For Each key As String In _tabs.Keys
1145 If key <> TabName AndAlso
1146 _tabs(key).Contains(Id) AndAlso
1147 _tabs(key).IsInnerStorageTabType AndAlso
1148 Not _tabs(key).Posts(Id).IsRead Then
1149 If _tabs(key).UnreadManage Then
1150 _tabs(key).UnreadCount -= 1
1151 If _tabs(key).OldestUnreadId = Id Then _tabs(key).OldestUnreadId = -1
1153 _tabs(key).Posts(Id).IsRead = True
1158 'If tb.OldestUnreadId > Id OrElse tb.OldestUnreadId = -1 Then tb.OldestUnreadId = Id
1159 If tb.OldestUnreadId > Id Then tb.OldestUnreadId = Id
1160 If tb.IsInnerStorageTabType Then
1162 If _statuses.ContainsKey(Id) AndAlso _statuses(Id).IsRead Then
1163 For Each key As String In _tabs.Keys
1164 If _tabs(key).UnreadManage AndAlso _
1165 _tabs(key).Contains(Id) AndAlso _
1166 Not _tabs(key).IsInnerStorageTabType Then
1167 _tabs(key).UnreadCount += 1
1168 If _tabs(key).OldestUnreadId > Id Then _tabs(key).OldestUnreadId = Id
1171 _statuses(Id).IsRead = False
1175 For Each key As String In _tabs.Keys
1176 If key <> TabName AndAlso _
1177 _tabs(key).UnreadManage AndAlso _
1178 _tabs(key).Contains(Id) AndAlso _
1179 Not _tabs(key).IsInnerStorageTabType Then
1180 _tabs(key).UnreadCount += 1
1181 If _tabs(key).OldestUnreadId > Id Then _tabs(key).OldestUnreadId = Id
1186 For Each key As String In _tabs.Keys
1187 If key <> TabName AndAlso
1188 _tabs(key).Contains(Id) AndAlso
1189 _tabs(key).IsInnerStorageTabType AndAlso
1190 _tabs(key).Posts(Id).IsRead Then
1191 If _tabs(key).UnreadManage Then
1192 _tabs(key).UnreadCount += 1
1193 If _tabs(key).OldestUnreadId > Id Then _tabs(key).OldestUnreadId = Id
1195 _tabs(key).Posts(Id).IsRead = False
1202 ''' TODO: パフォーマンスを勘案して、戻すか決める
1203 Public Sub SetRead(ByVal Read As Boolean, ByVal TabName As String, ByVal Index As Integer)
1204 'Read:True=既読へ False=未読へ
1205 Dim tb As TabClass = _tabs(TabName)
1207 If tb.UnreadManage = False Then Exit Sub '未読管理していなければ終了
1209 Dim Id As Long = tb.GetId(Index)
1210 If Id < 0 Then Exit Sub
1211 Dim post As PostClass
1212 If Not tb.IsInnerStorageTabType Then
1213 post = _statuses(Id)
1218 If post.IsRead = Read Then Exit Sub '状態変更なければ終了
1220 post.IsRead = Read '指定の状態に変更
1225 Me.SetNextUnreadId(Id, tb) '次の未読セット
1226 '他タブの最古未読IDはタブ切り替え時に。
1227 If tb.IsInnerStorageTabType Then Exit Sub
1228 For Each key As String In _tabs.Keys
1229 If key <> TabName AndAlso _
1230 _tabs(key).UnreadManage AndAlso _
1231 _tabs(key).Contains(Id) AndAlso _
1232 Not _tabs(key).IsInnerStorageTabType Then
1233 _tabs(key).UnreadCount -= 1
1234 If _tabs(key).OldestUnreadId = Id Then _tabs(key).OldestUnreadId = -1
1239 'If tb.OldestUnreadId > Id OrElse tb.OldestUnreadId = -1 Then tb.OldestUnreadId = Id
1240 If tb.OldestUnreadId > Id Then tb.OldestUnreadId = Id
1241 If tb.IsInnerStorageTabType Then Exit Sub
1242 For Each key As String In _tabs.Keys
1243 If Not key = TabName AndAlso _
1244 _tabs(key).UnreadManage AndAlso _
1245 _tabs(key).Contains(Id) AndAlso _
1246 Not _tabs(key).IsInnerStorageTabType Then
1247 _tabs(key).UnreadCount += 1
1248 If _tabs(key).OldestUnreadId > Id Then _tabs(key).OldestUnreadId = Id
1255 Public Sub SetRead()
1256 Dim tb As TabClass = GetTabByType(TabUsageType.Home)
1257 If tb.UnreadManage = False Then Exit Sub
1260 For i As Integer = 0 To tb.AllCount - 1
1261 Dim id As Long = tb.GetId(i)
1262 If id < 0 Then Exit Sub
1263 If Not _statuses(id).IsReply AndAlso _
1264 Not _statuses(id).IsRead AndAlso _
1265 Not _statuses(id).FilterHit Then
1266 _statuses(id).IsRead = True
1267 Me.SetNextUnreadId(id, tb) '次の未読セット
1268 For Each key As String In _tabs.Keys
1269 If _tabs(key).UnreadManage AndAlso _
1270 _tabs(key).Contains(id) Then
1271 _tabs(key).UnreadCount -= 1
1272 If _tabs(key).OldestUnreadId = id Then _tabs(key).OldestUnreadId = -1
1280 Public ReadOnly Property Item(ByVal ID As Long) As PostClass
1282 If _statuses.ContainsKey(ID) Then Return _statuses(ID)
1283 For Each tb As TabClass In Me.GetTabsInnerStorageType
1284 If tb.Contains(ID) Then
1292 Public ReadOnly Property Item(ByVal TabName As String, ByVal Index As Integer) As PostClass
1294 If Not _tabs.ContainsKey(TabName) Then Throw New ArgumentException("TabName=" + TabName + " is not contained.")
1295 Dim id As Long = _tabs(TabName).GetId(Index)
1296 If id < 0 Then Throw New ArgumentException("Index can't find. Index=" + Index.ToString + "/TabName=" + TabName)
1298 If _tabs(TabName).IsInnerStorageTabType Then
1299 Return _tabs(TabName).Posts(_tabs(TabName).GetId(Index))
1301 Return _statuses(_tabs(TabName).GetId(Index))
1303 Catch ex As Exception
1304 Throw New Exception("Index=" + Index.ToString + "/TabName=" + TabName, ex)
1309 Public ReadOnly Property Item(ByVal TabName As String, ByVal StartIndex As Integer, ByVal EndIndex As Integer) As PostClass()
1311 Dim length As Integer = EndIndex - StartIndex + 1
1312 Dim posts() As PostClass = New PostClass(length - 1) {}
1313 If _tabs(TabName).IsInnerStorageTabType Then
1314 For i As Integer = 0 To length - 1
1315 posts(i) = _tabs(TabName).Posts(_tabs(TabName).GetId(StartIndex + i))
1318 For i As Integer = 0 To length - 1
1319 posts(i) = _statuses(_tabs(TabName).GetId(StartIndex + i))
1326 'Public ReadOnly Property ItemCount() As Integer
1329 ' Return _statuses.Count 'DM,公式検索は除く
1334 Public Function ContainsKey(ByVal Id As Long) As Boolean
1337 Return _statuses.ContainsKey(Id)
1341 Public Function ContainsKey(ByVal Id As Long, ByVal TabName As String) As Boolean
1344 If _tabs.ContainsKey(TabName) Then
1345 Return _tabs(TabName).Contains(Id)
1352 Public Sub SetUnreadManage(ByVal Manage As Boolean)
1354 For Each key As String In _tabs.Keys
1355 Dim tb As TabClass = _tabs(key)
1356 If tb.UnreadManage Then
1358 Dim cnt As Integer = 0
1359 Dim oldest As Long = Long.MaxValue
1360 Dim posts As Dictionary(Of Long, PostClass)
1361 If Not tb.IsInnerStorageTabType Then
1366 For Each id As Long In tb.BackupIds
1367 If Not posts(id).IsRead Then
1369 If oldest > id Then oldest = id
1372 If oldest = Long.MaxValue Then oldest = -1
1373 tb.OldestUnreadId = oldest
1374 tb.UnreadCount = cnt
1379 For Each key As String In _tabs.Keys
1380 Dim tb As TabClass = _tabs(key)
1381 If tb.UnreadManage AndAlso tb.UnreadCount > 0 Then
1384 tb.OldestUnreadId = -1
1391 Public Sub RenameTab(ByVal Original As String, ByVal NewName As String)
1392 Dim tb As TabClass = _tabs(Original)
1393 _tabs.Remove(Original)
1394 tb.TabName = NewName
1395 _tabs.Add(NewName, tb)
1398 Public Sub FilterAll()
1400 Dim tbr As TabClass = GetTabByType(TabUsageType.Home)
1401 Dim replyTab As TabClass = GetTabByType(TabUsageType.Mentions)
1402 For Each key As String In _tabs.Keys
1403 Dim tb As TabClass = _tabs(key)
1404 If tb.FilterModified Then
1405 tb.FilterModified = False
1406 Dim orgIds() As Long = tb.BackupIds()
1408 ''''''''''''''フィルター前のIDsを退避。どのタブにも含まれないidはrecentへ追加
1409 ''''''''''''''moveフィルターにヒットした際、recentに該当あればrecentから削除
1410 For Each id As Long In _statuses.Keys
1411 Dim post As PostClass = _statuses.Item(id)
1412 If post.IsDm Then Continue For
1413 Dim rslt As HITRESULT = HITRESULT.None
1414 rslt = tb.AddFiltered(post)
1416 Case HITRESULT.CopyAndMark
1417 post.IsMark = True 'マークあり
1418 post.FilterHit = True
1420 tbr.Remove(post.StatusId, post.IsRead)
1422 post.FilterHit = True
1425 post.FilterHit = True
1426 Case HITRESULT.Exclude
1427 If key = replyTab.TabName AndAlso post.IsReply Then post.IsExcludeReply = True
1428 If post.IsFav Then GetTabByType(TabUsageType.Favorites).Add(post.StatusId, post.IsRead, True)
1429 post.FilterHit = False
1431 If key = replyTab.TabName AndAlso post.IsReply Then replyTab.Add(post.StatusId, post.IsRead, True)
1432 If post.IsFav Then GetTabByType(TabUsageType.Favorites).Add(post.StatusId, post.IsRead, True)
1433 post.FilterHit = False
1436 tb.AddSubmit() '振分確定
1437 For Each id As Long In orgIds
1438 Dim hit As Boolean = False
1439 For Each tkey As String In _tabs.Keys
1440 If _tabs(tkey).Contains(id) Then
1445 If Not hit Then tbr.Add(id, _statuses(id).IsRead, False)
1453 Public Function GetId(ByVal TabName As String, ByVal IndexCollection As ListView.SelectedIndexCollection) As Long()
1454 If IndexCollection.Count = 0 Then Return Nothing
1456 Dim tb As TabClass = _tabs(TabName)
1457 Dim Ids(IndexCollection.Count - 1) As Long
1458 For i As Integer = 0 To Ids.Length - 1
1459 Ids(i) = tb.GetId(IndexCollection(i))
1464 Public Function GetId(ByVal TabName As String, ByVal Index As Integer) As Long
1465 Return _tabs(TabName).GetId(Index)
1468 Public Function IndexOf(ByVal TabName As String, ByVal Ids() As Long) As Integer()
1469 If Ids Is Nothing Then Return Nothing
1470 Dim idx(Ids.Length - 1) As Integer
1471 Dim tb As TabClass = _tabs(TabName)
1472 For i As Integer = 0 To Ids.Length - 1
1473 idx(i) = tb.IndexOf(Ids(i))
1478 Public Function IndexOf(ByVal TabName As String, ByVal Id As Long) As Integer
1479 Return _tabs(TabName).IndexOf(Id)
1482 Public Sub ClearTabIds(ByVal TabName As String)
1485 If Not _tabs(TabName).IsInnerStorageTabType Then
1486 For Each Id As Long In _tabs(TabName).BackupIds
1487 Dim Hit As Boolean = False
1488 For Each tb As TabClass In _tabs.Values
1489 If tb.Contains(Id) Then
1494 If Not Hit Then _statuses.Remove(Id)
1499 _tabs(TabName).ClearIDs()
1503 Public Sub SetTabUnreadManage(ByVal TabName As String, ByVal Manage As Boolean)
1504 Dim tb As TabClass = _tabs(TabName)
1507 Dim cnt As Integer = 0
1508 Dim oldest As Long = Long.MaxValue
1509 Dim posts As Dictionary(Of Long, PostClass)
1510 If Not tb.IsInnerStorageTabType Then
1515 For Each id As Long In tb.BackupIds
1516 If Not posts(id).IsRead Then
1518 If oldest > id Then oldest = id
1521 If oldest = Long.MaxValue Then oldest = -1
1522 tb.OldestUnreadId = oldest
1523 tb.UnreadCount = cnt
1525 tb.OldestUnreadId = -1
1529 tb.UnreadManage = Manage
1532 Public Sub RefreshOwl(ByVal follower As List(Of Long))
1534 If follower.Count > 0 Then
1535 For Each post As PostClass In _statuses.Values
1536 'If post.UserId = 0 OrElse post.IsDm Then Continue For
1540 post.IsOwl = Not follower.Contains(post.UserId)
1544 For Each id As Long In _statuses.Keys
1545 _statuses(id).IsOwl = False
1551 Public Function GetTabByType(ByVal tabType As TabUsageType) As TabClass
1552 'Home,Mentions,DM,Favは1つに制限する
1553 'その他のタイプを指定されたら、最初に合致したものを返す
1556 For Each tb As TabClass In _tabs.Values
1557 If tb IsNot Nothing AndAlso tb.TabType = tabType Then Return tb
1563 Public Function GetTabsByType(ByVal tabType As TabUsageType) As List(Of TabClass)
1567 Dim tbs As New List(Of TabClass)
1568 For Each tb As TabClass In _tabs.Values
1569 If (tabType And tb.TabType) = tb.TabType Then tbs.Add(tb)
1575 Public Function GetTabsInnerStorageType() As List(Of TabClass)
1579 Dim tbs As New List(Of TabClass)
1580 For Each tb As TabClass In _tabs.Values
1581 If tb.IsInnerStorageTabType Then tbs.Add(tb)
1587 Public Function GetTabByName(ByVal tabName As String) As TabClass
1589 If _tabs.ContainsKey(tabName) Then Return _tabs(tabName)
1595 Public Function IsDefaultTab(ByVal tabName As String) As Boolean
1596 If tabName IsNot Nothing AndAlso _
1597 _tabs.ContainsKey(tabName) AndAlso _
1598 (_tabs(tabName).TabType = TabUsageType.Home OrElse _
1599 _tabs(tabName).TabType = TabUsageType.Mentions OrElse _
1600 _tabs(tabName).TabType = TabUsageType.DirectMessage OrElse _
1601 _tabs(tabName).TabType = TabUsageType.Favorites) Then
1609 Public Function IsDistributableTab(ByVal tabName As String) As Boolean
1610 Return tabName IsNot Nothing AndAlso
1611 _tabs.ContainsKey(tabName) AndAlso
1612 (_tabs(tabName).TabType = TabUsageType.Mentions OrElse
1613 _tabs(tabName).TabType = TabUsageType.UserDefined)
1616 Public Function GetUniqueTabName() As String
1617 Dim tabNameTemp As String = "MyTab" + (_tabs.Count + 1).ToString
1618 For i As Integer = 2 To 100
1619 If _tabs.ContainsKey(tabNameTemp) Then
1620 tabNameTemp = "MyTab" + (_tabs.Count + i).ToString
1628 Public ReadOnly Property Posts() As Dictionary(Of Long, PostClass)
1636 Public NotInheritable Class TabClass
1637 Private _unreadManage As Boolean = False
1638 Private _filters As List(Of FiltersClass)
1639 Private _unreadCount As Integer = 0
1640 Private _ids As List(Of Long)
1641 Private _tmpIds As New List(Of TemporaryId)
1642 Private _tabType As TabUsageType = TabUsageType.Undefined
1643 Private _sorter As New IdComparerClass
1645 Private ReadOnly _lockObj As New Object
1647 Public Property User As String
1651 Private _searchLang As String = ""
1652 Private _searchWords As String = ""
1653 Private _nextPageQuery As String = ""
1655 Public Property SearchLang() As String
1659 Set(ByVal value As String)
1664 Public Property SearchWords() As String
1668 Set(ByVal value As String)
1670 _searchWords = value.Trim
1674 Public Property NextPageQuery() As String
1676 Return _nextPageQuery
1678 Set(ByVal value As String)
1679 _nextPageQuery = value
1683 Public Function GetSearchPage(ByVal count As Integer) As Integer
1684 Return ((_ids.Count \ count) + 1)
1686 Private _beforeQuery As New Dictionary(Of String, String)
1687 Public Sub SaveQuery(ByVal more As Boolean)
1688 Dim qry As New Dictionary(Of String, String)
1689 If String.IsNullOrEmpty(_searchWords) Then
1693 qry.Add("q", _searchWords)
1694 If Not String.IsNullOrEmpty(_searchLang) Then qry.Add("lang", _searchLang)
1698 Public Function IsQueryChanged() As Boolean
1699 Dim qry As New Dictionary(Of String, String)
1700 If Not String.IsNullOrEmpty(_searchWords) Then
1701 qry.Add("q", _searchWords)
1702 If Not String.IsNullOrEmpty(_searchLang) Then qry.Add("lang", _searchLang)
1704 If qry.Count <> _beforeQuery.Count Then Return True
1706 For Each kvp As KeyValuePair(Of String, String) In qry
1707 If Not _beforeQuery.ContainsKey(kvp.Key) OrElse _beforeQuery(kvp.Key) <> kvp.Value Then
1715 Private _listInfo As ListElement
1716 Public Property ListInfo() As ListElement
1720 Set(ByVal value As ListElement)
1726 <Xml.Serialization.XmlIgnore()> _
1727 Public Property RelationTargetPost() As PostClass
1729 <Xml.Serialization.XmlIgnore()> _
1730 Public Property OldestId() As Long = Long.MaxValue
1732 <Xml.Serialization.XmlIgnore()> _
1733 Public Property SinceId() As Long
1735 <Xml.Serialization.XmlIgnore()> _
1736 Public Property Posts() As New Dictionary(Of Long, PostClass)
1738 Public Function GetTemporaryPosts() As PostClass()
1739 Dim tempPosts As New List(Of PostClass)
1740 If _tmpIds.Count = 0 Then Return tempPosts.ToArray
1741 For Each tempId As TemporaryId In _tmpIds
1742 tempPosts.Add(_Posts(tempId.Id))
1744 Return tempPosts.ToArray
1747 Public Function GetTemporaryCount() As Integer
1748 Return _tmpIds.Count
1751 Private Structure TemporaryId
1753 Public Read As Boolean
1755 Public Sub New(ByVal argId As Long, ByVal argRead As Boolean)
1762 _filters = New List(Of FiltersClass)
1765 _unreadManage = True
1766 _ids = New List(Of Long)
1767 Me.OldestUnreadId = -1
1768 _tabType = TabUsageType.Undefined
1772 Public Sub New(ByVal TabName As String, ByVal TabType As TabUsageType, ByVal list As ListElement)
1774 _filters = New List(Of FiltersClass)
1777 _unreadManage = True
1778 _ids = New List(Of Long)
1779 Me.OldestUnreadId = -1
1782 If Me.IsInnerStorageTabType Then
1783 _sorter.posts = _Posts
1785 _sorter.posts = TabInformations.GetInstance.Posts
1790 If _sorter.Mode = IdComparerClass.ComparerMode.Id Then
1791 _ids.Sort(_sorter.CmpMethod)
1794 Dim ar() As Long = Nothing
1795 If _sorter.Order = SortOrder.Ascending Then
1796 Select Case _sorter.Mode
1797 Case IdComparerClass.ComparerMode.Data
1798 ar = _ids.OrderBy(Function(n) _sorter.posts(n).TextFromApi).ToArray
1799 Case IdComparerClass.ComparerMode.Name
1800 ar = _ids.OrderBy(Function(n) _sorter.posts(n).ScreenName).ToArray
1801 Case IdComparerClass.ComparerMode.Nickname
1802 ar = _ids.OrderBy(Function(n) _sorter.posts(n).Nickname).ToArray
1803 Case IdComparerClass.ComparerMode.Source
1804 ar = _ids.OrderBy(Function(n) _sorter.posts(n).Source).ToArray
1807 Select Case _sorter.Mode
1808 Case IdComparerClass.ComparerMode.Data
1809 ar = _ids.OrderByDescending(Function(n) _sorter.posts(n).TextFromApi).ToArray
1810 Case IdComparerClass.ComparerMode.Name
1811 ar = _ids.OrderByDescending(Function(n) _sorter.posts(n).ScreenName).ToArray
1812 Case IdComparerClass.ComparerMode.Nickname
1813 ar = _ids.OrderByDescending(Function(n) _sorter.posts(n).Nickname).ToArray
1814 Case IdComparerClass.ComparerMode.Source
1815 ar = _ids.OrderByDescending(Function(n) _sorter.posts(n).Source).ToArray
1818 _ids = New List(Of Long)(ar)
1821 Public ReadOnly Property Sorter() As IdComparerClass
1828 Private Sub Add(ByVal ID As Long, ByVal Read As Boolean)
1829 If Me._ids.Contains(ID) Then Exit Sub
1831 If Me.Sorter.Mode = IdComparerClass.ComparerMode.Id Then
1832 If Me.Sorter.Order = SortOrder.Ascending Then
1835 Me._ids.Insert(0, ID)
1841 If Not Read AndAlso Me._unreadManage Then
1842 Me._unreadCount += 1
1843 If ID < Me.OldestUnreadId Then Me.OldestUnreadId = ID
1844 'If Me.OldestUnreadId = -1 Then
1845 ' Me.OldestUnreadId = ID
1847 ' If ID < Me.OldestUnreadId Then Me.OldestUnreadId = ID
1852 Public Sub Add(ByVal ID As Long, ByVal Read As Boolean, ByVal Temporary As Boolean)
1853 If Not Temporary Then
1856 _tmpIds.Add(New TemporaryId(ID, Read))
1861 Public Function AddFiltered(ByVal post As PostClass) As HITRESULT
1862 If Me.IsInnerStorageTabType Then Return HITRESULT.None
1864 Dim rslt As HITRESULT = HITRESULT.None
1866 SyncLock Me._lockObj
1867 For Each ft As FiltersClass In _filters
1868 Select Case ft.IsHit(post) 'フィルタクラスでヒット判定
1871 If rslt <> HITRESULT.CopyAndMark Then rslt = HITRESULT.Copy
1872 Case HITRESULT.CopyAndMark
1873 rslt = HITRESULT.CopyAndMark
1875 rslt = HITRESULT.Move
1876 Case HITRESULT.Exclude
1877 rslt = HITRESULT.Exclude
1883 If rslt <> HITRESULT.None AndAlso rslt <> HITRESULT.Exclude Then
1884 _tmpIds.Add(New TemporaryId(post.StatusId, post.IsRead))
1887 Return rslt 'マーク付けは呼び出し元で行うこと
1891 Public Sub AddPostToInnerStorage(ByVal Post As PostClass)
1892 If _Posts.ContainsKey(Post.StatusId) Then Exit Sub
1893 _Posts.Add(Post.StatusId, Post)
1894 _tmpIds.Add(New TemporaryId(Post.StatusId, Post.IsRead))
1897 Public Sub AddSubmit(ByRef isMentionIncluded As Boolean)
1898 If _tmpIds.Count = 0 Then Exit Sub
1899 _tmpIds.Sort(Function(x As TemporaryId, y As TemporaryId) x.Id.CompareTo(y.Id))
1900 For Each tId As TemporaryId In _tmpIds
1901 If Me.TabType = TabUsageType.Mentions AndAlso TabInformations.GetInstance.Item(tId.Id).IsReply Then isMentionIncluded = True
1902 Me.Add(tId.Id, tId.Read)
1907 Public Sub AddSubmit()
1908 Dim mention As Boolean
1912 Public Sub Remove(ByVal Id As Long)
1913 If Not Me._ids.Contains(Id) Then Exit Sub
1915 If Me.IsInnerStorageTabType Then _Posts.Remove(Id)
1918 Public Sub Remove(ByVal Id As Long, ByVal Read As Boolean)
1919 If Not Me._ids.Contains(Id) Then Exit Sub
1921 If Not Read AndAlso Me._unreadManage Then
1922 Me._unreadCount -= 1
1923 Me.OldestUnreadId = -1
1927 If Me.IsInnerStorageTabType Then _Posts.Remove(Id)
1930 Public Property UnreadManage() As Boolean
1932 Return _unreadManage
1934 Set(ByVal value As Boolean)
1935 Me._unreadManage = value
1937 Me.OldestUnreadId = -1
1943 Public Property Notify() As Boolean
1945 Public Property SoundFile() As String = ""
1947 <Xml.Serialization.XmlIgnore()> _
1948 Public Property OldestUnreadId() As Long = -1
1950 <Xml.Serialization.XmlIgnore()> _
1951 Public Property UnreadCount() As Integer
1953 Return If(Me.UnreadManage AndAlso AppendSettingDialog.Instance.UnreadManage, _unreadCount, 0)
1955 Set(ByVal value As Integer)
1956 If value < 0 Then value = 0
1957 _unreadCount = value
1961 Public ReadOnly Property AllCount() As Integer
1963 Return Me._ids.Count
1967 Public Function GetFilters() As FiltersClass()
1968 SyncLock Me._lockObj
1969 Return _filters.ToArray()
1973 Public Sub RemoveFilter(ByVal filter As FiltersClass)
1974 SyncLock Me._lockObj
1975 _filters.Remove(filter)
1976 Me.FilterModified = True
1980 Public Function AddFilter(ByVal filter As FiltersClass) As Boolean
1981 SyncLock Me._lockObj
1982 If _filters.Contains(filter) Then Return False
1983 _filters.Add(filter)
1984 Me.FilterModified = True
1989 Public Sub EditFilter(ByVal original As FiltersClass, ByVal modified As FiltersClass)
1990 original.BodyFilter = modified.BodyFilter
1991 original.NameFilter = modified.NameFilter
1992 original.SearchBoth = modified.SearchBoth
1993 original.SearchUrl = modified.SearchUrl
1994 original.UseRegex = modified.UseRegex
1995 original.CaseSensitive = modified.CaseSensitive
1996 original.IsRt = modified.IsRt
1997 original.UseLambda = modified.UseLambda
1998 original.Source = modified.Source
1999 original.ExBodyFilter = modified.ExBodyFilter
2000 original.ExNameFilter = modified.ExNameFilter
2001 original.ExSearchBoth = modified.ExSearchBoth
2002 original.ExSearchUrl = modified.ExSearchUrl
2003 original.ExUseRegex = modified.ExUseRegex
2004 original.ExCaseSensitive = modified.ExCaseSensitive
2005 original.IsExRt = modified.IsExRt
2006 original.ExUseLambda = modified.ExUseLambda
2007 original.ExSource = modified.ExSource
2008 original.MoveFrom = modified.MoveFrom
2009 original.SetMark = modified.SetMark
2010 Me.FilterModified = True
2013 <Xml.Serialization.XmlIgnore()> _
2014 Public Property Filters() As List(Of FiltersClass)
2016 SyncLock Me._lockObj
2020 Set(ByVal value As List(Of FiltersClass))
2021 SyncLock Me._lockObj
2027 Public Property FilterArray() As FiltersClass()
2029 SyncLock Me._lockObj
2030 Return _filters.ToArray
2033 Set(ByVal value As FiltersClass())
2034 SyncLock Me._lockObj
2035 For Each filters As FiltersClass In value
2036 _filters.Add(filters)
2041 Public Function Contains(ByVal ID As Long) As Boolean
2042 Return _ids.Contains(ID)
2045 Public Sub ClearIDs()
2049 Me.OldestUnreadId = -1
2050 If _Posts IsNot Nothing Then
2055 Public Function GetId(ByVal Index As Integer) As Long
2056 Return If(Index < _ids.Count, _ids(Index), -1)
2059 Public Function IndexOf(ByVal ID As Long) As Integer
2060 Return _ids.IndexOf(ID)
2063 <Xml.Serialization.XmlIgnore()> _
2064 Public Property FilterModified() As Boolean
2066 Public Function BackupIds() As Long()
2067 Return _ids.ToArray()
2070 Public Property TabName() As String = ""
2072 Public Property TabType() As TabUsageType
2076 Set(ByVal value As TabUsageType)
2078 If Me.IsInnerStorageTabType Then
2079 _sorter.posts = _Posts
2081 _sorter.posts = TabInformations.GetInstance.Posts
2086 Public ReadOnly Property IsInnerStorageTabType As Boolean
2088 If _tabType = TabUsageType.PublicSearch OrElse
2089 _tabType = TabUsageType.DirectMessage OrElse
2090 _tabType = TabUsageType.Lists OrElse
2091 _tabType = TabUsageType.UserTimeline OrElse
2092 _tabType = TabUsageType.Related Then
2102 Public NotInheritable Class FiltersClass
2103 Implements System.IEquatable(Of FiltersClass)
2104 Private _name As String = ""
2105 Private _body As New List(Of String)
2106 Private _searchBoth As Boolean = True
2107 Private _searchUrl As Boolean = False
2108 Private _caseSensitive As Boolean = False
2109 Private _useRegex As Boolean = False
2110 Private _isRt As Boolean = False
2111 Private _source As String = ""
2112 Private _exname As String = ""
2113 Private _exbody As New List(Of String)
2114 Private _exsearchBoth As Boolean = True
2115 Private _exsearchUrl As Boolean = False
2116 Private _exuseRegex As Boolean = False
2117 Private _excaseSensitive As Boolean = False
2118 Private _isExRt As Boolean = False
2119 Private _exSource As String = ""
2120 Private _moveFrom As Boolean = False
2121 Private _setMark As Boolean = True
2122 Private _useLambda As Boolean = False
2123 Private _exuseLambda As Boolean = False
2126 Private _lambdaExp As LambdaExpression = Nothing
2127 Private _lambdaExpDelegate As [Delegate] = Nothing
2128 Private _exlambdaExp As LambdaExpression = Nothing
2129 Private _exlambdaExpDelegate As [Delegate] = Nothing
2136 Private Function MakeSummary() As String
2137 Dim fs As New StringBuilder()
2138 If Not String.IsNullOrEmpty(_name) OrElse _body.Count > 0 OrElse _isRt OrElse Not String.IsNullOrEmpty(_source) Then
2140 If Not String.IsNullOrEmpty(_name) Then
2141 fs.AppendFormat(My.Resources.SetFiltersText1, _name)
2143 fs.Append(My.Resources.SetFiltersText2)
2146 If _body.Count > 0 Then
2147 fs.Append(My.Resources.SetFiltersText3)
2148 For Each bf As String In _body
2153 fs.Append(My.Resources.SetFiltersText4)
2157 fs.Append(My.Resources.SetFiltersText5)
2159 fs.Append(My.Resources.SetFiltersText6)
2162 fs.Append(My.Resources.SetFiltersText7)
2165 fs.Append(My.Resources.SetFiltersText8)
2167 If _caseSensitive Then
2168 fs.Append(My.Resources.SetFiltersText13)
2174 fs.Append("LambdaExp/")
2176 If Not String.IsNullOrEmpty(_source) Then
2177 fs.AppendFormat("Src…{0}/", _source)
2182 If Not String.IsNullOrEmpty(_exname) OrElse _exbody.Count > 0 OrElse _isExRt OrElse Not String.IsNullOrEmpty(_exSource) Then
2184 fs.Append(My.Resources.SetFiltersText12)
2185 If _exsearchBoth Then
2186 If Not String.IsNullOrEmpty(_exname) Then
2187 fs.AppendFormat(My.Resources.SetFiltersText1, _exname)
2189 fs.Append(My.Resources.SetFiltersText2)
2192 If _exbody.Count > 0 Then
2193 fs.Append(My.Resources.SetFiltersText3)
2194 For Each bf As String In _exbody
2199 fs.Append(My.Resources.SetFiltersText4)
2202 If _exsearchBoth Then
2203 fs.Append(My.Resources.SetFiltersText5)
2205 fs.Append(My.Resources.SetFiltersText6)
2208 fs.Append(My.Resources.SetFiltersText7)
2210 If _exsearchUrl Then
2211 fs.Append(My.Resources.SetFiltersText8)
2213 If _excaseSensitive Then
2214 fs.Append(My.Resources.SetFiltersText13)
2219 If _exuseLambda Then
2220 fs.Append("LambdaExp/")
2222 If Not String.IsNullOrEmpty(_exSource) Then
2223 fs.AppendFormat("Src…{0}/", _exSource)
2231 fs.Append(My.Resources.SetFiltersText9)
2233 fs.Append(My.Resources.SetFiltersText11)
2235 If Not _moveFrom AndAlso _setMark Then
2236 fs.Append(My.Resources.SetFiltersText10)
2237 ElseIf Not _moveFrom Then
2243 Return fs.ToString()
2246 Public Property NameFilter() As String
2250 Set(ByVal value As String)
2255 Public Property ExNameFilter() As String
2259 Set(ByVal value As String)
2264 <Xml.Serialization.XmlIgnore()> _
2265 Public Property BodyFilter() As List(Of String)
2269 Set(ByVal value As List(Of String))
2270 _lambdaExp = Nothing
2271 _lambdaExpDelegate = Nothing
2276 Public Property BodyFilterArray() As String()
2278 Return _body.ToArray
2280 Set(ByVal value As String())
2281 _body = New List(Of String)
2282 For Each filter As String In value
2288 <Xml.Serialization.XmlIgnore()> _
2289 Public Property ExBodyFilter() As List(Of String)
2293 Set(ByVal value As List(Of String))
2294 _exlambdaExp = Nothing
2295 _exlambdaExpDelegate = Nothing
2300 Public Property ExBodyFilterArray() As String()
2302 Return _exbody.ToArray
2304 Set(ByVal value As String())
2305 _exbody = New List(Of String)
2306 For Each filter As String In value
2312 Public Property SearchBoth() As Boolean
2316 Set(ByVal value As Boolean)
2321 Public Property ExSearchBoth() As Boolean
2323 Return _exsearchBoth
2325 Set(ByVal value As Boolean)
2326 _exsearchBoth = value
2330 Public Property MoveFrom() As Boolean
2334 Set(ByVal value As Boolean)
2339 Public Property SetMark() As Boolean
2343 Set(ByVal value As Boolean)
2348 Public Property SearchUrl() As Boolean
2352 Set(ByVal value As Boolean)
2357 Public Property ExSearchUrl() As Boolean
2361 Set(ByVal value As Boolean)
2362 _exsearchUrl = value
2366 Public Property CaseSensitive() As Boolean
2368 Return _caseSensitive
2370 Set(ByVal value As Boolean)
2371 _caseSensitive = value
2375 Public Property ExCaseSensitive() As Boolean
2377 Return _excaseSensitive
2379 Set(ByVal value As Boolean)
2380 _excaseSensitive = value
2384 Public Property UseLambda() As Boolean
2388 Set(ByVal value As Boolean)
2389 _lambdaExp = Nothing
2390 _lambdaExpDelegate = Nothing
2395 Public Property ExUseLambda() As Boolean
2399 Set(ByVal value As Boolean)
2400 _exlambdaExp = Nothing
2401 _exlambdaExpDelegate = Nothing
2402 _exuseLambda = value
2406 Public Property UseRegex() As Boolean
2410 Set(ByVal value As Boolean)
2415 Public Property ExUseRegex() As Boolean
2419 Set(ByVal value As Boolean)
2424 Public Property IsRt() As Boolean
2428 Set(ByVal value As Boolean)
2433 Public Property IsExRt() As Boolean
2437 Set(ByVal value As Boolean)
2442 Public Property Source() As String
2446 Set(ByVal value As String)
2451 Public Property ExSource() As String
2455 Set(ByVal value As String)
2460 Public Overrides Function ToString() As String
2461 Return MakeSummary()
2464 Public Function ExecuteLambdaExpression(ByVal expr As String, ByVal post As PostClass) As Boolean
2465 If _lambdaExp Is Nothing OrElse _lambdaExpDelegate Is Nothing Then
2466 _lambdaExp = ParseLambda(Of PostClass, Boolean)(expr, post)
2467 _lambdaExpDelegate = _lambdaExp.Compile()
2469 Return (DirectCast(_lambdaExpDelegate.DynamicInvoke(post), Boolean))
2472 Public Function ExecuteExLambdaExpression(ByVal expr As String, ByVal post As PostClass) As Boolean
2473 If _exlambdaExp Is Nothing OrElse _exlambdaExpDelegate Is Nothing Then
2474 _exlambdaExp = ParseLambda(Of PostClass, Boolean)(expr, post)
2475 _exlambdaExpDelegate = _exlambdaExp.Compile()
2477 Return (DirectCast(_exlambdaExpDelegate.DynamicInvoke(post), Boolean))
2480 Public Function IsHit(ByVal post As PostClass) As HITRESULT
2481 Dim bHit As Boolean = True
2483 Dim tSource As String
2486 tSource = post.SourceHtml
2488 tBody = post.TextFromApi
2489 tSource = post.Source
2492 Dim compOpt As System.StringComparison
2493 Dim rgOpt As System.Text.RegularExpressions.RegexOptions
2494 If _caseSensitive Then
2495 compOpt = StringComparison.Ordinal
2496 rgOpt = RegexOptions.None
2498 compOpt = StringComparison.OrdinalIgnoreCase
2499 rgOpt = RegexOptions.IgnoreCase
2502 If String.IsNullOrEmpty(_name) OrElse
2503 (Not _useRegex AndAlso
2504 (post.ScreenName.Equals(_name, compOpt) OrElse
2505 post.RetweetedBy.Equals(_name, compOpt)
2509 (Regex.IsMatch(post.ScreenName, _name, rgOpt) OrElse
2510 (Not String.IsNullOrEmpty(post.RetweetedBy) AndAlso Regex.IsMatch(post.RetweetedBy, _name, rgOpt))
2514 If Not ExecuteLambdaExpression(_body.Item(0), post) Then bHit = False
2516 For Each fs As String In _body
2518 If Not Regex.IsMatch(tBody, fs, rgOpt) Then bHit = False
2520 If _caseSensitive Then
2521 If Not tBody.Contains(fs) Then bHit = False
2523 If Not tBody.ToLower().Contains(fs.ToLower()) Then bHit = False
2526 If Not bHit Then Exit For
2534 If Not ExecuteLambdaExpression(_body.Item(0), post) Then bHit = False
2536 For Each fs As String In _body
2538 If Not (Regex.IsMatch(post.ScreenName, fs, rgOpt) OrElse
2539 (Not String.IsNullOrEmpty(post.RetweetedBy) AndAlso Regex.IsMatch(post.RetweetedBy, fs, rgOpt)) OrElse
2540 Regex.IsMatch(tBody, fs, rgOpt)) Then bHit = False
2542 If _caseSensitive Then
2543 If Not (post.ScreenName.Contains(fs) OrElse _
2544 post.RetweetedBy.Contains(fs) OrElse _
2545 tBody.Contains(fs)) Then bHit = False
2547 If Not (post.ScreenName.ToLower().Contains(fs.ToLower()) OrElse _
2548 post.RetweetedBy.ToLower().Contains(fs.ToLower()) OrElse _
2549 tBody.ToLower().Contains(fs.ToLower())) Then bHit = False
2552 If Not bHit Then Exit For
2557 If post.RetweetedId = 0 Then bHit = False
2559 If Not String.IsNullOrEmpty(_source) Then
2561 If Not Regex.IsMatch(tSource, _source, rgOpt) Then bHit = False
2563 If Not tSource.Equals(_source, compOpt) Then bHit = False
2568 If _exsearchUrl Then
2570 tSource = post.SourceHtml
2572 tBody = post.TextFromApi
2573 tSource = post.Source
2576 Dim exFlag As Boolean = False
2577 If Not String.IsNullOrEmpty(_exname) OrElse _exbody.Count > 0 Then
2578 If _excaseSensitive Then
2579 compOpt = StringComparison.Ordinal
2580 rgOpt = RegexOptions.None
2582 compOpt = StringComparison.OrdinalIgnoreCase
2583 rgOpt = RegexOptions.IgnoreCase
2585 If _exsearchBoth Then
2586 If String.IsNullOrEmpty(_exname) OrElse
2587 (Not _exuseRegex AndAlso
2588 (post.ScreenName.Equals(_exname, compOpt) OrElse
2589 post.RetweetedBy.Equals(_exname, compOpt)
2592 (_exuseRegex AndAlso _
2593 (Regex.IsMatch(post.ScreenName, _exname, rgOpt) OrElse _
2594 (Not String.IsNullOrEmpty(post.RetweetedBy) AndAlso Regex.IsMatch(post.RetweetedBy, _exname, rgOpt))
2597 If _exbody.Count > 0 Then
2598 If _exuseLambda Then
2599 If ExecuteExLambdaExpression(_exbody.Item(0), post) Then exFlag = True
2601 For Each fs As String In _exbody
2603 If Regex.IsMatch(tBody, fs, rgOpt) Then exFlag = True
2605 If _excaseSensitive Then
2606 If tBody.Contains(fs) Then exFlag = True
2608 If tBody.ToLower().Contains(fs.ToLower()) Then exFlag = True
2611 If exFlag Then Exit For
2619 If _exuseLambda Then
2620 If ExecuteExLambdaExpression(_exbody.Item(0), post) Then exFlag = True
2622 For Each fs As String In _exbody
2624 If Regex.IsMatch(post.ScreenName, fs, rgOpt) OrElse
2625 (Not String.IsNullOrEmpty(post.RetweetedBy) AndAlso Regex.IsMatch(post.RetweetedBy, fs, rgOpt)) OrElse
2626 Regex.IsMatch(tBody, fs, rgOpt) Then exFlag = True
2628 If _excaseSensitive Then
2629 If post.ScreenName.Contains(fs) OrElse _
2630 post.RetweetedBy.Contains(fs) OrElse _
2631 tBody.Contains(fs) Then exFlag = True
2633 If post.ScreenName.ToLower().Contains(fs.ToLower()) OrElse _
2634 post.RetweetedBy.ToLower().Contains(fs.ToLower()) OrElse _
2635 tBody.ToLower().Contains(fs.ToLower()) Then exFlag = True
2638 If exFlag Then Exit For
2644 If post.RetweetedId > 0 Then exFlag = True
2646 If Not String.IsNullOrEmpty(_exSource) Then
2648 If Regex.IsMatch(tSource, _exSource, rgOpt) Then exFlag = True
2650 If tSource.Equals(_exSource, compOpt) Then exFlag = True
2654 If String.IsNullOrEmpty(_name) AndAlso _body.Count = 0 AndAlso Not _isRt AndAlso String.IsNullOrEmpty(_source) Then
2660 Return HITRESULT.Move
2663 Return HITRESULT.CopyAndMark
2665 Return HITRESULT.Copy
2668 Return HITRESULT.Exclude
2672 Return HITRESULT.Exclude
2674 Return HITRESULT.None
2678 Return HITRESULT.None
2682 Public Overloads Function Equals(ByVal other As FiltersClass) As Boolean _
2683 Implements System.IEquatable(Of Tween.FiltersClass).Equals
2685 If Me.BodyFilter.Count <> other.BodyFilter.Count Then Return False
2686 If Me.ExBodyFilter.Count <> other.ExBodyFilter.Count Then Return False
2687 For i As Integer = 0 To Me.BodyFilter.Count - 1
2688 If Me.BodyFilter(i) <> other.BodyFilter(i) Then Return False
2690 For i As Integer = 0 To Me.ExBodyFilter.Count - 1
2691 If Me.ExBodyFilter(i) <> other.ExBodyFilter(i) Then Return False
2694 Return (Me.MoveFrom = other.MoveFrom) And
2695 (Me.SetMark = other.SetMark) And
2696 (Me.NameFilter = other.NameFilter) And
2697 (Me.SearchBoth = other.SearchBoth) And
2698 (Me.SearchUrl = other.SearchUrl) And
2699 (Me.UseRegex = other.UseRegex) And
2700 (Me.ExNameFilter = other.ExNameFilter) And
2701 (Me.ExSearchBoth = other.ExSearchBoth) And
2702 (Me.ExSearchUrl = other.ExSearchUrl) And
2703 (Me.ExUseRegex = other.ExUseRegex) And
2704 (Me.IsRt = other.IsRt) And
2705 (Me.Source = other.Source) And
2706 (Me.IsExRt = other.IsExRt) And
2707 (Me.ExSource = other.ExSource) And
2708 (Me.UseLambda = other.UseLambda) And
2709 (Me.ExUseLambda = other.ExUseLambda)
2712 Public Function CopyTo(ByVal destination As FiltersClass) As FiltersClass
2714 If Me.BodyFilter.Count > 0 Then
2715 For Each flt As String In Me.BodyFilter
2716 destination.BodyFilter.Add(String.Copy(flt))
2720 If Me.ExBodyFilter.Count > 0 Then
2721 For Each flt As String In Me.ExBodyFilter
2722 destination.ExBodyFilter.Add(String.Copy(flt))
2726 destination.MoveFrom = Me.MoveFrom
2727 destination.SetMark = Me.SetMark
2728 destination.NameFilter = Me.NameFilter
2729 destination.SearchBoth = Me.SearchBoth
2730 destination.SearchUrl = Me.SearchUrl
2731 destination.UseRegex = Me.UseRegex
2732 destination.ExNameFilter = Me.ExNameFilter
2733 destination.ExSearchBoth = Me.ExSearchBoth
2734 destination.ExSearchUrl = Me.ExSearchUrl
2735 destination.ExUseRegex = Me.ExUseRegex
2736 destination.IsRt = Me.IsRt
2737 destination.Source = Me.Source
2738 destination.IsExRt = Me.IsExRt
2739 destination.ExSource = Me.ExSource
2740 destination.UseLambda = Me.UseLambda
2741 destination.ExUseLambda = Me.ExUseLambda
2745 Public Overrides Function Equals(ByVal obj As Object) As Boolean
2746 If (obj Is Nothing) OrElse Not (Me.GetType() Is obj.GetType()) Then Return False
2747 Return Me.Equals(CType(obj, FiltersClass))
2750 Public Overrides Function GetHashCode() As Integer
2751 Return Me.MoveFrom.GetHashCode Xor
2752 Me.SetMark.GetHashCode Xor
2753 Me.BodyFilter.GetHashCode Xor
2754 Me.NameFilter.GetHashCode Xor
2755 Me.SearchBoth.GetHashCode Xor
2756 Me.SearchUrl.GetHashCode Xor
2757 Me.UseRegex.GetHashCode Xor
2758 Me.ExBodyFilter.GetHashCode Xor
2759 Me.ExNameFilter.GetHashCode Xor
2760 Me.ExSearchBoth.GetHashCode Xor
2761 Me.ExSearchUrl.GetHashCode Xor
2762 Me.ExUseRegex.GetHashCode Xor
2763 Me.IsRt.GetHashCode Xor
2764 Me.Source.GetHashCode Xor
2765 Me.IsExRt.GetHashCode Xor
2766 Me.ExSource.GetHashCode Xor
2767 Me.UseLambda.GetHashCode Xor
2768 Me.ExUseLambda.GetHashCode
2773 Public NotInheritable Class IdComparerClass
2774 Implements IComparer(Of Long)
2779 Public Enum ComparerMode
2787 Private _order As SortOrder
2788 Private _mode As ComparerMode
2789 Private _statuses As Dictionary(Of Long, PostClass)
2790 Private _CmpMethod As Comparison(Of Long)
2793 ''' 昇順か降順か Setの際は同時に比較関数の切り替えを行う
2795 Public Property Order() As SortOrder
2799 Set(ByVal Value As SortOrder)
2801 SetCmpMethod(_mode, _order)
2806 ''' 並び替えの方法 Setの際は同時に比較関数の切り替えを行う
2808 Public Property Mode() As ComparerMode
2812 Set(ByVal Value As ComparerMode)
2814 SetCmpMethod(_mode, _order)
2819 ''' ListViewItemComparerクラスのコンストラクタ(引数付は未使用)
2821 ''' <param name="col">並び替える列番号</param>
2822 ''' <param name="ord">昇順か降順か</param>
2823 ''' <param name="cmod">並び替えの方法</param>
2826 _order = SortOrder.Ascending
2827 _mode = ComparerMode.Id
2828 SetCmpMethod(_mode, _order)
2831 Public Property posts() As Dictionary(Of Long, PostClass)
2832 Set(ByVal value As Dictionary(Of Long, PostClass))
2840 ' 指定したソートモードとソートオーダーに従い使用する比較関数のアドレスを返す
2841 Public Overloads ReadOnly Property CmpMethod(ByVal _sortmode As ComparerMode, ByVal _sortorder As SortOrder) As Comparison(Of Long)
2843 Dim _method As Comparison(Of Long) = Nothing
2844 If _sortorder = SortOrder.Ascending Then
2846 Select Case _sortmode
2847 Case ComparerMode.Data
2848 _method = AddressOf Compare_ModeData_Ascending
2849 Case ComparerMode.Id
2850 _method = AddressOf Compare_ModeId_Ascending
2851 Case ComparerMode.Name
2852 _method = AddressOf Compare_ModeName_Ascending
2853 Case ComparerMode.Nickname
2854 _method = AddressOf Compare_ModeNickName_Ascending
2855 Case ComparerMode.Source
2856 _method = AddressOf Compare_ModeSource_Ascending
2860 Select Case _sortmode
2861 Case ComparerMode.Data
2862 _method = AddressOf Compare_ModeData_Descending
2863 Case ComparerMode.Id
2864 _method = AddressOf Compare_ModeId_Descending
2865 Case ComparerMode.Name
2866 _method = AddressOf Compare_ModeName_Descending
2867 Case ComparerMode.Nickname
2868 _method = AddressOf Compare_ModeNickName_Descending
2869 Case ComparerMode.Source
2870 _method = AddressOf Compare_ModeSource_Descending
2877 ' ソートモードとソートオーダーに従い使用する比較関数のアドレスを返す
2878 ' (overload 現在の使用中の比較関数のアドレスを返す)
2879 Public Overloads ReadOnly Property CmpMethod() As Comparison(Of Long)
2885 ' ソートモードとソートオーダーに従い比較関数のアドレスを切り替え
2886 Private Sub SetCmpMethod(ByVal mode As ComparerMode, ByVal order As SortOrder)
2887 _CmpMethod = Me.CmpMethod(mode, order)
2890 'xがyより小さいときはマイナスの数、大きいときはプラスの数、
2891 '同じときは0を返す (こちらは未使用 一応比較関数群呼び出しの形のまま残しておく)
2892 Public Function Compare(ByVal x As Long, ByVal y As Long) _
2893 As Integer Implements IComparer(Of Long).Compare
2894 Return _CmpMethod(x, y)
2897 ' 比較用関数群 いずれもステータスIDの順序を考慮する
2899 Public Function Compare_ModeData_Ascending(ByVal x As Long, ByVal y As Long) As Integer
2900 Dim result As Integer = String.Compare(_statuses.Item(x).TextFromApi, _statuses.Item(y).TextFromApi)
2901 If result = 0 Then result = x.CompareTo(y)
2906 Public Function Compare_ModeData_Descending(ByVal x As Long, ByVal y As Long) As Integer
2907 Dim result As Integer = String.Compare(_statuses.Item(y).TextFromApi, _statuses.Item(x).TextFromApi)
2908 If result = 0 Then result = y.CompareTo(x)
2913 Public Function Compare_ModeId_Ascending(ByVal x As Long, ByVal y As Long) As Integer
2914 Return x.CompareTo(y)
2918 Public Function Compare_ModeId_Descending(ByVal x As Long, ByVal y As Long) As Integer
2919 Return y.CompareTo(x)
2923 Public Function Compare_ModeName_Ascending(ByVal x As Long, ByVal y As Long) As Integer
2924 Dim result As Integer = String.Compare(_statuses.Item(x).ScreenName, _statuses.Item(y).ScreenName)
2925 If result = 0 Then result = x.CompareTo(y)
2930 Public Function Compare_ModeName_Descending(ByVal x As Long, ByVal y As Long) As Integer
2931 Dim result As Integer = String.Compare(_statuses.Item(y).ScreenName, _statuses.Item(x).ScreenName)
2932 If result = 0 Then result = y.CompareTo(x)
2937 Public Function Compare_ModeNickName_Ascending(ByVal x As Long, ByVal y As Long) As Integer
2938 Dim result As Integer = String.Compare(_statuses.Item(x).Nickname, _statuses.Item(y).Nickname)
2939 If result = 0 Then result = x.CompareTo(y)
2944 Public Function Compare_ModeNickName_Descending(ByVal x As Long, ByVal y As Long) As Integer
2945 Dim result As Integer = String.Compare(_statuses.Item(y).Nickname, _statuses.Item(x).Nickname)
2946 If result = 0 Then result = y.CompareTo(x)
2951 Public Function Compare_ModeSource_Ascending(ByVal x As Long, ByVal y As Long) As Integer
2952 Dim result As Integer = String.Compare(_statuses.Item(x).Source, _statuses.Item(y).Source)
2953 If result = 0 Then result = x.CompareTo(y)
2958 Public Function Compare_ModeSource_Descending(ByVal x As Long, ByVal y As Long) As Integer
2959 Dim result As Integer = String.Compare(_statuses.Item(y).Source, _statuses.Item(x).Source)
2960 If result = 0 Then result = y.CompareTo(x)