OSDN Git Service

1d004817ed19c9fb6b4afee545c55e9d59182c21
[opentween/open-tween.git] / OpenTween / EventViewerDialog.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-2012 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
8 // All rights reserved.
9 // 
10 // This file is part of OpenTween.
11 // 
12 // This program is free software; you can redistribute it and/or modify it
13 // under the terms of the GNU General public License as published by the Free
14 // Software Foundation; either version 3 of the License, or (at your option)
15 // any later version.
16 // 
17 // This program is distributed in the hope that it will be useful, but
18 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License
20 // for more details. 
21 // 
22 // You should have received a copy of the GNU General public License along
23 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
24 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
25 // Boston, MA 02110-1301, USA.
26
27 using System;
28 using System.Collections.Generic;
29 using System.ComponentModel;
30 using System.Data;
31 using System.Diagnostics.CodeAnalysis;
32 using System.Drawing;
33 using System.Linq;
34 using System.Text;
35 using System.Windows.Forms;
36 using System.Text.RegularExpressions;
37 using System.IO;
38 using System.Globalization;
39 using OpenTween.Setting;
40
41 namespace OpenTween
42 {
43     public partial class EventViewerDialog : OTBaseForm
44     {
45         public List<Twitter.FormattedEvent> EventSource { get; set; }
46
47         private Twitter.FormattedEvent[] _filterdEventSource;
48
49         private ListViewItem[] _ItemCache = null;
50         private int _itemCacheIndex;
51
52         private TabPage _curTab = null;
53
54         public EventViewerDialog()
55         {
56             InitializeComponent();
57
58             // メイリオフォント指定時にタブの最小幅が広くなる問題の対策
59             this.TabEventType.HandleCreated += (s, e) => NativeMethods.SetMinTabWidth((TabControl)s, 40);
60         }
61
62         protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
63         {
64             base.ScaleControl(factor, specified);
65             ScaleChildControl(this.EventList, factor);
66         }
67
68         private void OK_Button_Click(object sender, EventArgs e)
69         {
70             this.DialogResult = DialogResult.OK;
71             this.Close();
72         }
73
74         private void Cancel_Button_Click(object sender, EventArgs e)
75         {
76             this.DialogResult = DialogResult.Cancel;
77             this.Close();
78         }
79
80         private ListViewItem CreateListViewItem(Twitter.FormattedEvent source)
81         {
82             string[] s = { source.CreatedAt.ToString(), source.Event.ToUpper(CultureInfo.CurrentCulture), source.Username, source.Target };
83             return new ListViewItem(s);
84         }
85
86         private void EventViewerDialog_Shown(object sender, EventArgs e)
87         {
88             // タブ初期化
89             foreach (var tabPage in CreateTabsFromUserStreamsEvent())
90             {
91                 TabEventType.TabPages.Add(tabPage);
92             }
93
94             EventList.BeginUpdate();
95             _curTab = TabEventType.SelectedTab;
96             CreateFilterdEventSource();
97             EventList.EndUpdate();
98             this.TopMost = SettingManager.Common.AlwaysTop;
99         }
100
101         private async void EventList_DoubleClick(object sender, EventArgs e)
102         {
103             if (EventList.SelectedIndices.Count != 0 && _filterdEventSource[EventList.SelectedIndices[0]] != null)
104             {
105                 await ((TweenMain)this.Owner).OpenUriInBrowserAsync("https://twitter.com/" + _filterdEventSource[EventList.SelectedIndices[0]].Username);
106             }
107         }
108
109         private MyCommon.EVENTTYPE ParseEventTypeFromTag()
110         {
111             return (MyCommon.EVENTTYPE)Enum.Parse(typeof(MyCommon.EVENTTYPE), _curTab.Tag.ToString());
112         }
113
114         private bool IsFilterMatch(Twitter.FormattedEvent x)
115         {
116             if (!CheckBoxFilter.Checked || string.IsNullOrEmpty(TextBoxKeyword.Text))
117             {
118                 return true;
119             }
120             else
121             {
122                 if (CheckRegex.Checked)
123                 {
124                     try
125                     {
126                         Regex rx = new Regex(TextBoxKeyword.Text);
127                         return rx.Match(x.Username).Success || rx.Match(x.Target).Success;
128                     }
129                     catch (Exception ex)
130                     {
131                         MessageBox.Show(Properties.Resources.ButtonOK_ClickText3 + ex.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
132                         return false;
133                     }
134                 }
135                 else
136                 {
137                     return x.Username.Contains(TextBoxKeyword.Text) || x.Target.Contains(TextBoxKeyword.Text);
138                 }
139             }
140         }
141
142         private void CreateFilterdEventSource()
143         {
144             if (EventSource != null && EventSource.Count > 0)
145             {
146                 _filterdEventSource = EventSource.FindAll((x) => !(CheckExcludeMyEvent.Checked && x.IsMe) &&
147                                                                  (x.Eventtype & ParseEventTypeFromTag()) != 0 &&
148                                                                  IsFilterMatch(x)).ToArray();
149                 _ItemCache = null;
150                 EventList.VirtualListSize = _filterdEventSource.Count();
151                 StatusLabelCount.Text = string.Format("{0} / {1}", _filterdEventSource.Count(), EventSource.Count());
152             }
153             else
154             {
155                 StatusLabelCount.Text = "0 / 0";
156             }
157         }
158
159         private void CheckExcludeMyEvent_CheckedChanged(object sender, EventArgs e)
160         {
161             CreateFilterdEventSource();
162         }
163
164         private void ButtonRefresh_Click(object sender, EventArgs e)
165         {
166             CreateFilterdEventSource();
167         }
168
169         private void TabEventType_SelectedIndexChanged(object sender, EventArgs e)
170         {
171             CreateFilterdEventSource();
172         }
173
174         private void TabEventType_Selecting(object sender, TabControlCancelEventArgs e)
175         {
176             _curTab = e.TabPage;
177             if (!e.TabPage.Controls.Contains(EventList))
178             {
179                 e.TabPage.Controls.Add(EventList);
180             }
181         }
182
183         private void TextBoxKeyword_KeyPress(object sender, KeyPressEventArgs e)
184         {
185             if (e.KeyChar == (char)Keys.Enter)
186             {
187                 CreateFilterdEventSource();
188                 e.Handled = true;
189             }
190         }
191
192         private void EventList_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
193         {
194             if (_ItemCache != null && e.ItemIndex >= _itemCacheIndex && e.ItemIndex < _itemCacheIndex + _ItemCache.Length)
195             {
196                 //キャッシュヒット
197                 e.Item = _ItemCache[e.ItemIndex - _itemCacheIndex];
198             }
199             else
200             {
201                 //キャッシュミス
202                 e.Item = CreateListViewItem(_filterdEventSource[e.ItemIndex]);
203             }
204         }
205
206         private void EventList_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e)
207         {
208             CreateCache(e.StartIndex, e.EndIndex);
209         }
210
211         private void CreateCache(int StartIndex, int EndIndex)
212         {
213             //キャッシュ要求(要求範囲±30を作成)
214             StartIndex -= 30;
215             if (StartIndex < 0) StartIndex = 0;
216             EndIndex += 30;
217             if (EndIndex > _filterdEventSource.Count() - 1)
218             {
219                 EndIndex = _filterdEventSource.Count() - 1;
220             }
221             _ItemCache = new ListViewItem[] { };
222             Array.Resize(ref _ItemCache, EndIndex - StartIndex + 1);
223             _itemCacheIndex = StartIndex;
224             for (int i = 0; i < _ItemCache.Length; i++)
225             {
226                 _ItemCache[i] = CreateListViewItem(_filterdEventSource[StartIndex + i]);
227             }
228         }
229
230         private void SaveLogButton_Click(object sender, EventArgs e)
231         {
232             DialogResult rslt = MessageBox.Show(string.Format(Properties.Resources.SaveLogMenuItem_ClickText5, Environment.NewLine),
233                     Properties.Resources.SaveLogMenuItem_ClickText2,
234                     MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
235             switch (rslt)
236             {
237                 case DialogResult.Yes:
238                     SaveFileDialog1.FileName = MyCommon.GetAssemblyName() + "Events" + _curTab.Tag + DateTime.Now.ToString("yyMMdd-HHmmss") + ".tsv";
239                     break;
240                 case DialogResult.No:
241                     SaveFileDialog1.FileName = MyCommon.GetAssemblyName() + "Events" + DateTime.Now.ToString("yyMMdd-HHmmss") + ".tsv";
242                     break;
243                 default:
244                     return;
245             }
246
247             SaveFileDialog1.InitialDirectory = Application.StartupPath;
248             SaveFileDialog1.Filter = Properties.Resources.SaveLogMenuItem_ClickText3;
249             SaveFileDialog1.FilterIndex = 0;
250             SaveFileDialog1.Title = Properties.Resources.SaveLogMenuItem_ClickText4;
251             SaveFileDialog1.RestoreDirectory = true;
252
253             if (SaveFileDialog1.ShowDialog() == DialogResult.OK)
254             {
255                 if (!SaveFileDialog1.ValidateNames) return;
256                 using (StreamWriter sw = new StreamWriter(SaveFileDialog1.FileName, false, Encoding.UTF8))
257                 {
258                     switch (rslt)
259                     {
260                         case DialogResult.Yes:
261                             SaveEventLog(_filterdEventSource.ToList(), sw);
262                             break;
263                         case DialogResult.No:
264                             SaveEventLog(EventSource, sw);
265                             break;
266                         default:
267                             //
268                             break;
269                     }
270                 }
271             }
272             this.TopMost = SettingManager.Common.AlwaysTop;
273         }
274
275         private void SaveEventLog(List<Twitter.FormattedEvent> source, StreamWriter sw)
276         {
277             foreach (Twitter.FormattedEvent _event in source)
278             {
279                 sw.WriteLine(_event.Eventtype + "\t" +
280                              "\"" + _event.CreatedAt + "\"\t" +
281                              _event.Event + "\t" +
282                              _event.Username + "\t" +
283                              _event.Target + "\t" +
284                              _event.Id);
285             }
286         }
287
288         [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")]
289         private static IEnumerable<TabPage> CreateTabsFromUserStreamsEvent()
290         {
291             return Enum.GetNames(typeof(MyCommon.EVENTTYPE))
292                        .Where(e => e != "None" && e != "All")
293                        .Select(e => new TabPage(e)
294                        {
295                            // Name = "TabPage" + e,
296                            Tag = e,
297                            UseVisualStyleBackColor = true,
298                            AccessibleRole = AccessibleRole.PageTab,
299                        });
300         }
301     }
302 }