OSDN Git Service

C# 8.0 のnull許容参照型を有効化
[opentween/open-tween.git] / OpenTween / Models / FilterTabModel.cs
1 // OpenTween - 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>
7 //           (c) 2011      Egtra (@egtra) <http://dev.activebasic.com/egtra/>
8 //           (c) 2012      kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
9 // All rights reserved.
10 //
11 // This file is part of OpenTween.
12 //
13 // This program is free software; you can redistribute it and/or modify it
14 // under the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 3 of the License, or (at your option)
16 // any later version.
17 //
18 // This program is distributed in the hope that it will be useful, but
19 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 // for more details.
22 //
23 // You should have received a copy of the GNU General Public License along
24 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
25 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
26 // Boston, MA 02110-1301, USA.
27
28 #nullable enable
29
30 using System;
31 using System.Collections.Generic;
32 using System.ComponentModel;
33 using System.Linq;
34 using System.Text;
35 using System.Threading.Tasks;
36
37 namespace OpenTween.Models
38 {
39     public class FilterTabModel : TabModel
40     {
41         public override MyCommon.TabUsageType TabType
42             => MyCommon.TabUsageType.UserDefined;
43
44         public bool FilterModified { get; set; }
45
46         private readonly List<PostFilterRule> _filters = new List<PostFilterRule>();
47         private readonly object lockObjFilters = new object();
48
49         public FilterTabModel(string tabName) : base(tabName)
50         {
51         }
52
53         //フィルタに合致したら追加
54         public MyCommon.HITRESULT AddFiltered(PostClass post, bool immediately = false)
55         {
56             if (this.IsInnerStorageTabType)
57                 return MyCommon.HITRESULT.None;
58
59             var rslt = MyCommon.HITRESULT.None;
60
61             //全フィルタ評価(優先順位あり)
62             lock (this.lockObjFilters)
63             {
64                 foreach (var ft in _filters)
65                 {
66                     try
67                     {
68                         switch (ft.ExecFilter(post))   //フィルタクラスでヒット判定
69                         {
70                             case MyCommon.HITRESULT.None:
71                                 break;
72                             case MyCommon.HITRESULT.Copy:
73                                 if (rslt != MyCommon.HITRESULT.CopyAndMark) rslt = MyCommon.HITRESULT.Copy;
74                                 break;
75                             case MyCommon.HITRESULT.CopyAndMark:
76                                 rslt = MyCommon.HITRESULT.CopyAndMark;
77                                 break;
78                             case MyCommon.HITRESULT.Move:
79                                 rslt = MyCommon.HITRESULT.Move;
80                                 break;
81                             case MyCommon.HITRESULT.Exclude:
82                                 rslt = MyCommon.HITRESULT.Exclude;
83                                 goto exit_for;
84                         }
85                     }
86                     catch (NullReferenceException)
87                     {
88                         // ExecFilterでNullRef出る場合あり。暫定対応
89                         MyCommon.TraceOut("ExecFilterでNullRef: " + ft);
90                         rslt = MyCommon.HITRESULT.None;
91                     }
92                 }
93                 exit_for:
94                 ;
95             }
96
97             if (this.TabType != MyCommon.TabUsageType.Mute &&
98                 rslt != MyCommon.HITRESULT.None && rslt != MyCommon.HITRESULT.Exclude)
99             {
100                 if (immediately)
101                     this.AddPostImmediately(post.StatusId, post.IsRead);
102                 else
103                     this.AddPostQueue(post);
104             }
105
106             return rslt; //マーク付けは呼び出し元で行うこと
107         }
108
109
110         public PostFilterRule[] GetFilters()
111         {
112             lock (this.lockObjFilters)
113             {
114                 return _filters.ToArray();
115             }
116         }
117
118         public void RemoveFilter(PostFilterRule filter)
119         {
120             lock (this.lockObjFilters)
121             {
122                 _filters.Remove(filter);
123                 filter.PropertyChanged -= this.OnFilterModified;
124                 this.FilterModified = true;
125             }
126         }
127
128         public bool AddFilter(PostFilterRule filter)
129         {
130             lock (this.lockObjFilters)
131             {
132                 if (_filters.Contains(filter)) return false;
133                 filter.PropertyChanged += this.OnFilterModified;
134                 _filters.Add(filter);
135                 this.FilterModified = true;
136                 return true;
137             }
138         }
139
140         private void OnFilterModified(object sender, PropertyChangedEventArgs e)
141             => this.FilterModified = true;
142
143         public PostFilterRule[] FilterArray
144         {
145             get
146             {
147                 lock (this.lockObjFilters)
148                 {
149                     return _filters.ToArray();
150                 }
151             }
152             set
153             {
154                 lock (this.lockObjFilters)
155                 {
156                     foreach (var oldFilter in this._filters)
157                     {
158                         oldFilter.PropertyChanged -= this.OnFilterModified;
159                     }
160
161                     this._filters.Clear();
162                     this.FilterModified = true;
163
164                     foreach (var newFilter in value)
165                     {
166                         _filters.Add(newFilter);
167                         newFilter.PropertyChanged += this.OnFilterModified;
168                     }
169                 }
170             }
171         }
172
173         public override Task RefreshAsync(Twitter tw, bool backward, bool startup, IProgress<string> progress)
174         {
175             var homeTab = TabInformations.GetInstance().HomeTab;
176
177             return homeTab.RefreshAsync(tw, backward, startup, progress);
178         }
179     }
180 }