OSDN Git Service

ListViewのカラム幅のスケーリング処理をOTBaseFormに移動
[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
39 namespace OpenTween
40 {
41     public partial class EventViewerDialog : OTBaseForm
42     {
43         public List<Twitter.FormattedEvent> EventSource { get; set; }
44
45         private Twitter.FormattedEvent[] _filterdEventSource;
46
47         private ListViewItem[] _ItemCache = null;
48         private int _itemCacheIndex;
49
50         private TabPage _curTab = null;
51
52         public EventViewerDialog()
53         {
54             InitializeComponent();
55
56             // メイリオフォント指定時にタブの最小幅が広くなる問題の対策
57             this.TabEventType.HandleCreated += (s, e) => NativeMethods.SetMinTabWidth((TabControl)s, 40);
58         }
59
60         protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
61         {
62             base.ScaleControl(factor, specified);
63             ScaleChildControl(this.EventList, factor);
64         }
65
66         private void OK_Button_Click(object sender, EventArgs e)
67         {
68             this.DialogResult = DialogResult.OK;
69             this.Close();
70         }
71
72         private void Cancel_Button_Click(object sender, EventArgs e)
73         {
74             this.DialogResult = DialogResult.Cancel;
75             this.Close();
76         }
77
78         private ListViewItem CreateListViewItem(Twitter.FormattedEvent source)
79         {
80             string[] s = { source.CreatedAt.ToString(), source.Event.ToUpper(), source.Username, source.Target };
81             return new ListViewItem(s);
82         }
83
84         private void EventViewerDialog_Shown(object sender, EventArgs e)
85         {
86             // タブ初期化
87             foreach (var tabPage in CreateTabsFromUserStreamsEvent())
88             {
89                 TabEventType.TabPages.Add(tabPage);
90             }
91
92             EventList.BeginUpdate();
93             _curTab = TabEventType.SelectedTab;
94             CreateFilterdEventSource();
95             EventList.EndUpdate();
96             this.TopMost = SettingCommon.Instance.AlwaysTop;
97         }
98
99         private void EventList_DoubleClick(object sender, EventArgs e)
100         {
101             if (EventList.SelectedIndices.Count != 0 && _filterdEventSource[EventList.SelectedIndices[0]] != null)
102             {
103                 ((TweenMain)this.Owner).OpenUriAsync("https://twitter.com/" + _filterdEventSource[EventList.SelectedIndices[0]].Username);
104             }
105         }
106
107         private MyCommon.EVENTTYPE ParseEventTypeFromTag()
108         {
109             return (MyCommon.EVENTTYPE)Enum.Parse(typeof(MyCommon.EVENTTYPE), _curTab.Tag.ToString());
110         }
111
112         private bool IsFilterMatch(Twitter.FormattedEvent x)
113         {
114             if (!CheckBoxFilter.Checked || string.IsNullOrEmpty(TextBoxKeyword.Text))
115             {
116                 return true;
117             }
118             else
119             {
120                 if (CheckRegex.Checked)
121                 {
122                     try
123                     {
124                         Regex rx = new Regex(TextBoxKeyword.Text);
125                         return rx.Match(x.Username).Success || rx.Match(x.Target).Success;
126                     }
127                     catch (Exception ex)
128                     {
129                         MessageBox.Show(Properties.Resources.ButtonOK_ClickText3 + ex.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
130                         return false;
131                     }
132                 }
133                 else
134                 {
135                     return x.Username.Contains(TextBoxKeyword.Text) || x.Target.Contains(TextBoxKeyword.Text);
136                 }
137             }
138         }
139
140         private void CreateFilterdEventSource()
141         {
142             if (EventSource != null && EventSource.Count > 0)
143             {
144                 _filterdEventSource = EventSource.FindAll((x) => (CheckExcludeMyEvent.Checked ? !x.IsMe : true) &&
145                                                                  (x.Eventtype & ParseEventTypeFromTag()) != 0 &&
146                                                                  IsFilterMatch(x)).ToArray();
147                 _ItemCache = null;
148                 EventList.VirtualListSize = _filterdEventSource.Count();
149                 StatusLabelCount.Text = string.Format("{0} / {1}", _filterdEventSource.Count(), EventSource.Count());
150             }
151             else
152             {
153                 StatusLabelCount.Text = "0 / 0";
154             }
155         }
156
157         private void CheckExcludeMyEvent_CheckedChanged(object sender, EventArgs e)
158         {
159             CreateFilterdEventSource();
160         }
161
162         private void ButtonRefresh_Click(object sender, EventArgs e)
163         {
164             CreateFilterdEventSource();
165         }
166
167         private void TabEventType_SelectedIndexChanged(object sender, EventArgs e)
168         {
169             CreateFilterdEventSource();
170         }
171
172         private void TabEventType_Selecting(object sender, TabControlCancelEventArgs e)
173         {
174             _curTab = e.TabPage;
175             if (!e.TabPage.Controls.Contains(EventList))
176             {
177                 e.TabPage.Controls.Add(EventList);
178             }
179         }
180
181         private void TextBoxKeyword_KeyPress(object sender, KeyPressEventArgs e)
182         {
183             if (e.KeyChar == (char)Keys.Enter)
184             {
185                 CreateFilterdEventSource();
186                 e.Handled = true;
187             }
188         }
189
190         private void EventList_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
191         {
192             if (_ItemCache != null && e.ItemIndex >= _itemCacheIndex && e.ItemIndex < _itemCacheIndex + _ItemCache.Length)
193             {
194                 //キャッシュヒット
195                 e.Item = _ItemCache[e.ItemIndex - _itemCacheIndex];
196             }
197             else
198             {
199                 //キャッシュミス
200                 e.Item = CreateListViewItem(_filterdEventSource[e.ItemIndex]);
201             }
202         }
203
204         private void EventList_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e)
205         {
206             CreateCache(e.StartIndex, e.EndIndex);
207         }
208
209         private void CreateCache(int StartIndex, int EndIndex)
210         {
211             //キャッシュ要求(要求範囲±30を作成)
212             StartIndex -= 30;
213             if (StartIndex < 0) StartIndex = 0;
214             EndIndex += 30;
215             if (EndIndex > _filterdEventSource.Count() - 1)
216             {
217                 EndIndex = _filterdEventSource.Count() - 1;
218             }
219             _ItemCache = new ListViewItem[] { };
220             Array.Resize(ref _ItemCache, EndIndex - StartIndex + 1);
221             _itemCacheIndex = StartIndex;
222             for (int i = 0; i < _ItemCache.Length; i++)
223             {
224                 _ItemCache[i] = CreateListViewItem(_filterdEventSource[StartIndex + i]);
225             }
226         }
227
228         private void SaveLogButton_Click(object sender, EventArgs e)
229         {
230             DialogResult rslt = MessageBox.Show(string.Format(Properties.Resources.SaveLogMenuItem_ClickText5, Environment.NewLine),
231                     Properties.Resources.SaveLogMenuItem_ClickText2,
232                     MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
233             switch (rslt)
234             {
235                 case DialogResult.Yes:
236                     SaveFileDialog1.FileName = MyCommon.GetAssemblyName() + "Events" + _curTab.Tag.ToString() + DateTime.Now.ToString("yyMMdd-HHmmss") + ".tsv";
237                     break;
238                 case DialogResult.No:
239                     SaveFileDialog1.FileName = MyCommon.GetAssemblyName() + "Events" + DateTime.Now.ToString("yyMMdd-HHmmss") + ".tsv";
240                     break;
241                 default:
242                     return;
243             }
244
245             SaveFileDialog1.InitialDirectory = Application.StartupPath;
246             SaveFileDialog1.Filter = Properties.Resources.SaveLogMenuItem_ClickText3;
247             SaveFileDialog1.FilterIndex = 0;
248             SaveFileDialog1.Title = Properties.Resources.SaveLogMenuItem_ClickText4;
249             SaveFileDialog1.RestoreDirectory = true;
250
251             if (SaveFileDialog1.ShowDialog() == DialogResult.OK)
252             {
253                 if (!SaveFileDialog1.ValidateNames) return;
254                 using (StreamWriter sw = new StreamWriter(SaveFileDialog1.FileName, false, Encoding.UTF8))
255                 {
256                     switch (rslt)
257                     {
258                         case DialogResult.Yes:
259                             SaveEventLog(_filterdEventSource.ToList(), sw);
260                             break;
261                         case DialogResult.No:
262                             SaveEventLog(EventSource, sw);
263                             break;
264                         default:
265                             //
266                             break;
267                     }
268                 }
269             }
270             this.TopMost = SettingCommon.Instance.AlwaysTop;
271         }
272
273         private void SaveEventLog(List<Twitter.FormattedEvent> source, StreamWriter sw)
274         {
275             foreach (Twitter.FormattedEvent _event in source)
276             {
277                 sw.WriteLine(_event.Eventtype.ToString() + "\t" +
278                              "\"" + _event.CreatedAt.ToString() + "\"\t" +
279                              _event.Event + "\t" +
280                              _event.Username + "\t" +
281                              _event.Target + "\t" +
282                              _event.Id.ToString());
283             }
284         }
285
286         [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")]
287         private static IEnumerable<TabPage> CreateTabsFromUserStreamsEvent()
288         {
289             return Enum.GetNames(typeof(MyCommon.EVENTTYPE))
290                        .Where(e => e != "None" && e != "All")
291                        .Select(e => new TabPage(e)
292                        {
293                            // Name = "TabPage" + e,
294                            Tag = e,
295                            UseVisualStyleBackColor = true
296                        });
297         }
298     }
299 }