OSDN Git Service

描画関連の不具合対応
[opentween/open-tween.git] / Tween / Tween.vb
1 ' Tween - Client of Twitter
2 ' Copyright (c) 2007-2009 kiri_feather (@kiri_feather) <kiri_feather@gmail.com>
3 '           (c) 2008-2009 Moz (@syo68k) <http://iddy.jp/profile/moz/>
4 '           (c) 2008-2009 takeshik (@takeshik) <http://www.takeshik.org/>
5 ' All rights reserved.
6
7 ' This file is part of Tween.
8
9 ' This program is free software; you can redistribute it and/or modify it
10 ' under the terms of the GNU General Public License as published by the Free
11 ' Software Foundation; either version 3 of the License, or (at your option)
12 ' any later version.
13
14 ' This program is distributed in the hope that it will be useful, but
15 ' WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ' or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 ' for more details. 
18
19 ' You should have received a copy of the GNU General Public License along
20 ' with this program. If not, see <http://www.gnu.org/licenses/>, or write to
21 ' the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
22 ' Boston, MA 02110-1301, USA.
23
24 'コンパイル後コマンド
25 '"c:\Program Files\Microsoft.NET\SDK\v2.0\Bin\sgen.exe" /f /a:"$(TargetPath)"
26 '"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\sgen.exe" /f /a:"$(TargetPath)"
27
28
29 Imports System
30 Imports System.Text
31 Imports System.Text.RegularExpressions
32 Imports Tween.TweenCustomControl
33 Imports System.IO
34 Imports System.Web
35 Imports System.Reflection
36 Imports System.ComponentModel
37 Imports System.Diagnostics
38 Imports Microsoft.Win32
39
40 Public Class TweenMain
41
42     '各種設定
43     Private _username As String         'ユーザー名
44     Private _password As String         'パスワード(デクリプト済み)
45
46     Private _mySize As Size             '画面サイズ
47     Private _myLoc As Point             '画面位置
48     Private _mySpDis As Integer         '区切り位置
49     Private _mySpDis2 As Integer        '発言欄区切り位置
50     Private _iconSz As Integer            'アイコンサイズ(現在は16、24、48の3種類。将来直接数字指定可能とする 注:24x24の場合に26と指定しているのはMSゴシック系フォントのための仕様)
51     Private _iconCol As Boolean           '1列表示の時True(48サイズのとき)
52
53     '雑多なフラグ類
54     Private _initial As Boolean         'True:起動時処理中
55     Private _ignoreConfigSave As Boolean         'True:起動時処理中
56     'Private listViewItemSorter As ListViewItemComparer      'リストソート用カスタムクラス
57     Private _tabDrag As Boolean           'タブドラッグ中フラグ(DoDragDropを実行するかの判定用)
58     Private _rclickTabName As String      '右クリックしたタブの名前(Tabコントロール機能不足対応)
59     Private ReadOnly _syncObject As New Object()    'ロック用
60     Private Const detailHtmlFormatMono1 As String = "<html><head><style type=""text/css""><!-- pre {font-family: """
61     Private Const detailHtmlFormat2 As String = """, sans-serif; font-size: "
62     Private Const detailHtmlFormat3 As String = "pt; word-wrap: break-word; color:rgb("
63     Private Const detailHtmlFormat4 As String = ");} a:link, a:visited, a:active, a:hover {color:rgb("
64     Private Const detailHtmlFormat5 As String = "); } --></style></head><body style=""margin:0px; background-color:rgb("
65     Private Const detailHtmlFormatMono6 As String = ");""><pre>"
66     Private Const detailHtmlFormatMono7 As String = "</pre></body></html>"
67     Private Const detailHtmlFormat1 As String = "<html><head><style type=""text/css""><!-- p {font-family: """
68     Private Const detailHtmlFormat6 As String = ");""><p>"
69     Private Const detailHtmlFormat7 As String = "</p></body></html>"
70     Private detailHtmlFormatHeader As String
71     Private detailHtmlFormatFooter As String
72     Private _myStatusError As Boolean = False
73     Private _myStatusOnline As Boolean = False
74     Private soundfileListup As Boolean = False
75
76     '設定ファイル関連
77     'Private _cfg As SettingToConfig '旧
78     Private _cfgLocal As SettingLocal
79     Private _cfgCommon As SettingCommon
80     Private modifySettingLocal As Boolean = False
81     Private modifySettingCommon As Boolean = False
82     Private modifySettingAtId As Boolean = False
83
84     'サブ画面インスタンス
85     Private SettingDialog As New Setting()       '設定画面インスタンス
86     Private TabDialog As New TabsDialog()        'タブ選択ダイアログインスタンス
87     Private SearchDialog As New SearchWord()     '検索画面インスタンス
88     'Private _tabs As New List(Of TabStructure)() '要素TabStructureクラスのジェネリックリストインスタンス(タブ情報用)
89     Private fDialog As New FilterDialog() 'フィルター編集画面
90     Private UrlDialog As New OpenURL()
91     Private dialogAsShieldicon As DialogAsShieldIcon    ' シールドアイコン付きダイアログ
92     Private AtIdSupl As AtIdSupplement    '@id補助
93
94     '表示フォント、色、アイコン
95     Private _fntUnread As Font            '未読用フォント
96     Private _clUnread As Color            '未読用文字色
97     Private _fntReaded As Font            '既読用フォント
98     Private _clReaded As Color            '既読用文字色
99     Private _clFav As Color               'Fav用文字色
100     Private _clOWL As Color               '片思い用文字色
101     Private _clRetweet As Color               'Retweet用文字色
102     Private _fntDetail As Font            '発言詳細部用フォント
103     Private _clDetail As Color              '発言詳細部用色
104     Private _clDetailLink As Color          '発言詳細部用リンク文字色
105     Private _clDetailBackcolor As Color     '発言詳細部用背景色
106     Private _clSelf As Color              '自分の発言用背景色
107     Private _clAtSelf As Color            '自分宛返信用背景色
108     Private _clTarget As Color            '選択発言者の他の発言用背景色
109     Private _clAtTarget As Color          '選択発言中の返信先用背景色
110     Private _clAtFromTarget As Color      '選択発言者への返信発言用背景色
111     Private _clAtTo As Color              '選択発言の唯一@先
112     Private _clListBackcolor As Color       'リスト部通常発言背景色
113     Private _clInputBackcolor As Color      '入力欄背景色
114     Private _clInputFont As Color           '入力欄文字色
115     Private _fntInputFont As Font           '入力欄フォント
116     'Private TIconList As ImageList        '発言詳細部用アイコン画像リスト
117     Private TIconDic As Dictionary(Of String, Image)        '発言詳細部用アイコン画像リスト
118     Private TIconSmallList As ImageList   'リスト表示用アイコン画像リスト
119     Private NIconAt As Icon               'At.ico             タスクトレイアイコン:通常時
120     Private NIconAtRed As Icon            'AtRed.ico          タスクトレイアイコン:通信エラー時
121     Private NIconAtSmoke As Icon          'AtSmoke.ico        タスクトレイアイコン:オフライン時
122     Private NIconRefresh(3) As Icon       'Refresh.ico        タスクトレイアイコン:更新中(アニメーション用に4種類を保持するリスト)
123     Private TabIcon As Icon               'Tab.ico            未読のあるタブ用アイコン
124     Private MainIcon As Icon              'Main.ico           画面左上のアイコン
125     Private ReplyIcon As Icon               '5g
126     Private ReplyIconBlink As Icon          '6g
127
128     Private _anchorPost As PostClass
129     Private _anchorFlag As Boolean        'True:関連発言移動中(関連移動以外のオペレーションをするとFalseへ。Trueだとリスト背景色をアンカー発言選択中として描画)
130
131     Private _history As New List(Of String)()   '発言履歴
132     Private _hisIdx As Integer                  '発言履歴カレントインデックス
133
134     '発言投稿時のAPI引数(発言編集時に設定。手書きreplyでは設定されない)
135     Private _reply_to_id As Long     ' リプライ先のステータスID 0の場合はリプライではない 注:複数あてのものはリプライではない
136     Private _reply_to_name As String    ' リプライ先ステータスの書き込み者の名前
137
138     '時速表示用
139     Private _postTimestamps As New List(Of Date)()
140     Private _favTimestamps As New List(Of Date)()
141     Private _tlTimestamps As New Dictionary(Of Date, Integer)()
142     Private _tlCount As Integer
143
144     ' 以下DrawItem関連
145     Private _brsHighLight As New SolidBrush(Color.FromKnownColor(KnownColor.Highlight))
146     Private _brsHighLightText As New SolidBrush(Color.FromKnownColor(KnownColor.HighlightText))
147     Private _brsForeColorUnread As SolidBrush
148     Private _brsForeColorReaded As SolidBrush
149     Private _brsForeColorFav As SolidBrush
150     Private _brsForeColorOWL As SolidBrush
151     Private _brsForeColorRetweet As SolidBrush
152     Private _brsBackColorMine As SolidBrush
153     Private _brsBackColorAt As SolidBrush
154     Private _brsBackColorYou As SolidBrush
155     Private _brsBackColorAtYou As SolidBrush
156     Private _brsBackColorAtFromTarget As SolidBrush
157     Private _brsBackColorAtTo As SolidBrush
158     Private _brsBackColorNone As SolidBrush
159     Private _brsDeactiveSelection As New SolidBrush(Color.FromKnownColor(KnownColor.ButtonFace)) 'Listにフォーカスないときの選択行の背景色
160     Private sf As New StringFormat()
161     Private sfTab As New StringFormat()
162     'Private _columnIdx As Integer   'ListviewのDisplayIndex退避用(DrawItemで使用)
163     'Private _columnChangeFlag As Boolean
164
165     '''''''''''''''''''''''''''''''''''''''''''''''''''''
166     Private _statuses As TabInformations
167     Private _itemCache() As ListViewItem
168     Private _itemCacheIndex As Integer
169     Private _postCache() As PostClass
170     Private _curTab As TabPage
171     Private _curItemIndex As Integer
172     Private _curList As DetailsListView
173     Private _curPost As PostClass
174     'Private _waitFollower As Boolean = False
175     Private _waitTimeline As Boolean = False
176     Private _waitReply As Boolean = False
177     Private _waitDm As Boolean = False
178     Private _waitFav As Boolean = False
179     Private _bw(9) As BackgroundWorker
180     Private _bwFollower As BackgroundWorker
181     Private cMode As Integer
182     Private StatusLabel As New ToolStripLabelHistory
183     Private shield As New ShieldIcon
184     Private SecurityManager As InternetSecurityManager
185     '''''''''''''''''''''''''''''''''''''''''''''''''''''
186 #If DEBUG Then
187     Private _drawcount As Long = 0
188     Private _drawtime As Long = 0
189 #End If
190
191     'URL短縮のUndo用
192     Private Structure urlUndo
193         Public Before As String
194         Public After As String
195     End Structure
196
197     Private urlUndoBuffer As Generic.List(Of urlUndo) = Nothing
198
199     'Backgroundworkerの処理結果通知用引数構造体
200     Private Structure GetWorkerResult
201         Public retMsg As String                     '処理結果詳細メッセージ。エラー時に値がセットされる
202         'Public notifyPosts As List(Of PostClass) '取得した発言。Twitter.MyListItem構造体を要素としたジェネリックリスト
203         Public page As Integer                      '取得対象ページ番号
204         Public endPage As Integer                   '取得終了ページ番号(継続可能ならインクリメントされて返る。pageと比較して継続判定)
205         Public type As WORKERTYPE                   '処理種別
206         Public imgs As Dictionary(Of String, Image)                    '新規取得したアイコンイメージ
207         Public tName As String                      'Fav追加・削除時のタブ名
208         Public ids As List(Of Long)               'Fav追加・削除時のID
209         Public sIds As List(Of Long)                  'Fav追加・削除成功分のID
210         Public newDM As Boolean
211         'Public soundFile As String
212         Public addCount As Integer
213     End Structure
214
215     'Backgroundworkerへ処理内容を通知するための引数用構造体
216     Private Structure GetWorkerArg
217         Public page As Integer                      '処理対象ページ番号
218         Public endPage As Integer                   '処理終了ページ番号(起動時の読み込みページ数。通常時はpageと同じ値をセット)
219         Public type As WORKERTYPE                   '処理種別
220         Public status As String                     '発言POST時の発言内容
221         Public ids As List(Of Long)               'Fav追加・削除時のItemIndex
222         Public sIds As List(Of Long)              'Fav追加・削除成功分のItemIndex
223         Public tName As String                      'Fav追加・削除時のタブ名
224     End Structure
225
226     '検索処理タイプ
227     Private Enum SEARCHTYPE
228         DialogSearch
229         NextSearch
230         PrevSearch
231     End Enum
232
233     Private Sub TweenMain_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
234         '画面が他画面の裏に隠れると、アイコン画像が再描画されない問題の対応
235         If UserPicture.Image IsNot Nothing Then
236             UserPicture.Invalidate(False)
237         End If
238         '画面がアクティブになったら、発言欄の背景色戻す
239         If StatusText.Focused Then
240             Me.StatusText_Enter(Me.StatusText, System.EventArgs.Empty)
241         End If
242     End Sub
243
244     Private Sub TweenMain_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
245         '後始末
246         SettingDialog.Dispose()
247         TabDialog.Dispose()
248         SearchDialog.Dispose()
249         fDialog.Dispose()
250         UrlDialog.Dispose()
251         If TIconDic IsNot Nothing AndAlso TIconDic.Keys.Count > 0 Then
252             For Each key As String In TIconDic.Keys
253                 TIconDic(key).Dispose()
254             Next
255             TIconDic.Clear()
256         End If
257         If TIconSmallList IsNot Nothing Then TIconSmallList.Dispose()
258         If NIconAt IsNot Nothing Then NIconAt.Dispose()
259         If NIconAtRed IsNot Nothing Then NIconAtRed.Dispose()
260         If NIconAtSmoke IsNot Nothing Then NIconAtSmoke.Dispose()
261         If NIconRefresh(0) IsNot Nothing Then NIconRefresh(0).Dispose()
262         If NIconRefresh(1) IsNot Nothing Then NIconRefresh(1).Dispose()
263         If NIconRefresh(2) IsNot Nothing Then NIconRefresh(2).Dispose()
264         If NIconRefresh(3) IsNot Nothing Then NIconRefresh(3).Dispose()
265         If TabIcon IsNot Nothing Then TabIcon.Dispose()
266         If MainIcon IsNot Nothing Then MainIcon.Dispose()
267         If ReplyIcon IsNot Nothing Then ReplyIcon.Dispose()
268         If ReplyIconBlink IsNot Nothing Then ReplyIconBlink.Dispose()
269         _brsHighLight.Dispose()
270         _brsHighLightText.Dispose()
271         If _brsForeColorUnread IsNot Nothing Then _brsForeColorUnread.Dispose()
272         If _brsForeColorReaded IsNot Nothing Then _brsForeColorReaded.Dispose()
273         If _brsForeColorFav IsNot Nothing Then _brsForeColorFav.Dispose()
274         If _brsForeColorOWL IsNot Nothing Then _brsForeColorOWL.Dispose()
275         If _brsForeColorRetweet IsNot Nothing Then _brsForeColorRetweet.Dispose()
276         If _brsBackColorMine IsNot Nothing Then _brsBackColorMine.Dispose()
277         If _brsBackColorAt IsNot Nothing Then _brsBackColorAt.Dispose()
278         If _brsBackColorYou IsNot Nothing Then _brsBackColorYou.Dispose()
279         If _brsBackColorAtYou IsNot Nothing Then _brsBackColorAtYou.Dispose()
280         If _brsBackColorAtFromTarget IsNot Nothing Then _brsBackColorAtFromTarget.Dispose()
281         If _brsBackColorAtTo IsNot Nothing Then _brsBackColorAtTo.Dispose()
282         If _brsBackColorNone IsNot Nothing Then _brsBackColorNone.Dispose()
283         If _brsDeactiveSelection IsNot Nothing Then _brsDeactiveSelection.Dispose()
284         shield.Dispose()
285         StatusLabel.Dispose()
286         sf.Dispose()
287         sfTab.Dispose()
288         For Each bw As BackgroundWorker In _bw
289             If bw IsNot Nothing Then
290                 bw.Dispose()
291             End If
292         Next
293         If _bwFollower IsNot Nothing Then
294             _bwFollower.Dispose()
295         End If
296     End Sub
297
298     Private Sub LoadIcons()
299         '着せ替えアイコン対応
300         'タスクトレイ通常時アイコン
301         Dim dir As String = Application.StartupPath
302
303         NIconAt = My.Resources.At
304         NIconAtRed = My.Resources.AtRed
305         NIconAtSmoke = My.Resources.AtSmoke
306         NIconRefresh(0) = My.Resources.Refresh
307         NIconRefresh(1) = My.Resources.Refresh2
308         NIconRefresh(2) = My.Resources.Refresh3
309         NIconRefresh(3) = My.Resources.Refresh4
310         TabIcon = My.Resources.TabIcon
311         MainIcon = My.Resources.MIcon
312         ReplyIcon = My.Resources.Reply
313         ReplyIconBlink = My.Resources.ReplyBlink
314
315         If Not Directory.Exists(Path.Combine(dir, "Icons")) Then
316             Exit Sub
317         End If
318
319         If File.Exists(Path.Combine(dir, "Icons\At.ico")) Then
320             Try
321                 NIconAt = New Icon(Path.Combine(dir, "Icons\At.ico"))
322             Catch ex As Exception
323             End Try
324         End If
325         'タスクトレイエラー時アイコン
326         If File.Exists(Path.Combine(dir, "Icons\AtRed.ico")) Then
327             Try
328                 NIconAtRed = New Icon(Path.Combine(dir, "Icons\AtRed.ico"))
329             Catch ex As Exception
330             End Try
331         End If
332         'タスクトレイオフライン時アイコン
333         If File.Exists(Path.Combine(dir, "Icons\AtSmoke.ico")) Then
334             Try
335                 NIconAtSmoke = New Icon(Path.Combine(dir, "Icons\AtSmoke.ico"))
336             Catch ex As Exception
337             End Try
338         End If
339         'タスクトレイ更新中アイコン
340         'アニメーション対応により4種類読み込み
341         If File.Exists(Path.Combine(dir, "Icons\Refresh.ico")) Then
342             Try
343                 NIconRefresh(0) = New Icon(Path.Combine(dir, "Icons\Refresh.ico"))
344             Catch ex As Exception
345             End Try
346         End If
347         If File.Exists(Path.Combine(dir, "Icons\Refresh2.ico")) Then
348             Try
349                 NIconRefresh(1) = New Icon(Path.Combine(dir, "Icons\Refresh2.ico"))
350             Catch ex As Exception
351             End Try
352         End If
353         If File.Exists(Path.Combine(dir, "Icons\Refresh3.ico")) Then
354             Try
355                 NIconRefresh(2) = New Icon(Path.Combine(dir, "Icons\Refresh3.ico"))
356             Catch ex As Exception
357             End Try
358         End If
359         If File.Exists(Path.Combine(dir, "Icons\Refresh4.ico")) Then
360             Try
361                 NIconRefresh(3) = New Icon(Path.Combine(dir, "Icons\Refresh4.ico"))
362             Catch ex As Exception
363             End Try
364         End If
365         'タブ見出し未読表示アイコン
366         If File.Exists(Path.Combine(dir, "Icons\Tab.ico")) Then
367             Try
368                 TabIcon = New Icon(Path.Combine(dir, "Icons\Tab.ico"))
369             Catch ex As Exception
370             End Try
371         End If
372         '画面のアイコン
373         If File.Exists(Path.Combine(dir, "Icons\MIcon.ico")) Then
374             Try
375                 MainIcon = New Icon(Path.Combine(dir, "Icons\MIcon.ico"))
376             Catch ex As Exception
377             End Try
378         End If
379         'Replyのアイコン
380         If File.Exists(Path.Combine(dir, "Icons\Reply.ico")) Then
381             Try
382                 ReplyIcon = New Icon(Path.Combine(dir, "Icons\Reply.ico"))
383             Catch ex As Exception
384             End Try
385         End If
386         'Reply点滅のアイコン
387         If File.Exists(Path.Combine(dir, "Icons\ReplyBlink.ico")) Then
388             Try
389                 ReplyIconBlink = New Icon(Path.Combine(dir, "Icons\ReplyBlink.ico"))
390             Catch ex As Exception
391             End Try
392         End If
393     End Sub
394
395     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
396         _ignoreConfigSave = True
397         Me.Visible = False
398         SecurityManager = New InternetSecurityManager(PostBrowser)
399
400         VerUpMenuItem.Image = shield.Icon
401         If Not My.Application.CommandLineArgs.Count = 0 AndAlso My.Application.CommandLineArgs.Contains("/d") Then TraceFlag = True
402         Me.StatusStrip1.Items.Add(StatusLabel)
403
404         fileVersion = _
405             System.Diagnostics.FileVersionInfo.GetVersionInfo( _
406             System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion
407
408         LoadIcons() ' アイコン読み込み
409
410         '発言保持クラス
411         _statuses = TabInformations.GetInstance()
412
413         'アイコン設定
414         Me.Icon = MainIcon              'メインフォーム(TweenMain)
415         NotifyIcon1.Icon = NIconAt      'タスクトレイ
416         TabImage.Images.Add(TabIcon)    'タブ見出し
417
418         ContextMenuStrip1.OwnerItem = Nothing
419         ContextMenuStrip2.OwnerItem = Nothing
420         ContextMenuTabProperty.OwnerItem = Nothing
421
422         SettingDialog.Owner = Me
423         SearchDialog.Owner = Me
424         fDialog.Owner = Me
425         TabDialog.Owner = Me
426         UrlDialog.Owner = Me
427
428         _history.Add("")
429         _hisIdx = 0
430         _reply_to_id = 0
431         _reply_to_name = ""
432
433         '<<<<<<<<<設定関連>>>>>>>>>
434         '設定コンバージョン
435         ConvertConfig()
436
437         ''設定読み出し
438         'ユーザー名とパスワードの取得
439         _username = _cfgCommon.UserName
440         _password = _cfgCommon.Password
441         '新着バルーン通知のチェック状態設定
442         NewPostPopMenuItem.Checked = _cfgCommon.NewAllPop
443
444         'フォント&文字色&背景色保持
445         _fntUnread = _cfgLocal.FontUnread
446         _clUnread = _cfgLocal.ColorUnread
447         _fntReaded = _cfgLocal.FontRead
448         _clReaded = _cfgLocal.ColorRead
449         _clFav = _cfgLocal.ColorFav
450         _clOWL = _cfgLocal.ColorOWL
451         _clRetweet = _cfgLocal.ColorRetweet
452         _fntDetail = _cfgLocal.FontDetail
453         _clDetail = _cfgLocal.ColorDetail
454         _clDetailLink = _cfgLocal.ColorDetailLink
455         _clDetailBackcolor = _cfgLocal.ColorDetailBackcolor
456         _clSelf = _cfgLocal.ColorSelf
457         _clAtSelf = _cfgLocal.ColorAtSelf
458         _clTarget = _cfgLocal.ColorTarget
459         _clAtTarget = _cfgLocal.ColorAtTarget
460         _clAtFromTarget = _cfgLocal.ColorAtFromTarget
461         _clAtTo = _cfgLocal.ColorAtTo
462         _clListBackcolor = _cfgLocal.ColorListBackcolor
463         _clInputBackcolor = _cfgLocal.ColorInputBackcolor
464         _clInputFont = _cfgLocal.ColorInputFont
465         _fntInputFont = _cfgLocal.FontInputFont
466
467         _brsForeColorUnread = New SolidBrush(_clUnread)
468         _brsForeColorReaded = New SolidBrush(_clReaded)
469         _brsForeColorFav = New SolidBrush(_clFav)
470         _brsForeColorOWL = New SolidBrush(_clOWL)
471         _brsForeColorRetweet = New SolidBrush(_clRetweet)
472         _brsBackColorMine = New SolidBrush(_clSelf)
473         _brsBackColorAt = New SolidBrush(_clAtSelf)
474         _brsBackColorYou = New SolidBrush(_clTarget)
475         _brsBackColorAtYou = New SolidBrush(_clAtTarget)
476         _brsBackColorAtFromTarget = New SolidBrush(_clAtFromTarget)
477         _brsBackColorAtTo = New SolidBrush(_clAtTo)
478         '_brsBackColorNone = New SolidBrush(Color.FromKnownColor(KnownColor.Window))
479         _brsBackColorNone = New SolidBrush(_clListBackcolor)
480
481         ' StringFormatオブジェクトへの事前設定
482         sf.Alignment = StringAlignment.Near
483         sf.LineAlignment = StringAlignment.Near
484         sfTab.Alignment = StringAlignment.Center
485         sfTab.LineAlignment = StringAlignment.Center
486
487         '設定画面への反映
488         SettingDialog.UserID = _username                                'ユーザ名
489         SettingDialog.PasswordStr = _password                           'パスワード
490         SettingDialog.TimelinePeriodInt = _cfgCommon.TimelinePeriod
491         SettingDialog.ReplyPeriodInt = _cfgCommon.ReplyPeriod
492         SettingDialog.DMPeriodInt = _cfgCommon.DMPeriod
493         SettingDialog.NextPageThreshold = _cfgCommon.NextPageThreshold
494         SettingDialog.NextPagesInt = _cfgCommon.NextPages
495         SettingDialog.MaxPostNum = _cfgCommon.MaxPostNum
496
497         '起動時読み込みページ数
498         SettingDialog.ReadPages = _cfgCommon.ReadPages
499         SettingDialog.ReadPagesReply = _cfgCommon.ReadPagesReply
500         SettingDialog.ReadPagesDM = _cfgCommon.ReadPagesDM
501
502         '起動時読み込み分を既読にするか。Trueなら既読として処理
503         SettingDialog.Readed = _cfgCommon.Read
504         '新着取得時のリストスクロールをするか。Trueならスクロールしない
505         ListLockMenuItem.Checked = _cfgCommon.ListLock
506         SettingDialog.IconSz = _cfgCommon.IconSize
507         '文末ステータス
508         SettingDialog.Status = _cfgLocal.StatusText
509         '未読管理。Trueなら未読管理する
510         SettingDialog.UnreadManage = _cfgCommon.UnreadManage
511         'サウンド再生(タブ別設定より優先)
512         SettingDialog.PlaySound = _cfgCommon.PlaySound
513         PlaySoundMenuItem.Checked = SettingDialog.PlaySound
514         '片思い表示。Trueなら片思い表示する
515         SettingDialog.OneWayLove = _cfgCommon.OneWayLove
516         'フォント&文字色&背景色
517         SettingDialog.FontUnread = _fntUnread
518         SettingDialog.ColorUnread = _clUnread
519         SettingDialog.FontReaded = _fntReaded
520         SettingDialog.ColorReaded = _clReaded
521         SettingDialog.ColorFav = _clFav
522         SettingDialog.ColorOWL = _clOWL
523         SettingDialog.ColorRetweet = _clRetweet
524         SettingDialog.FontDetail = _fntDetail
525         SettingDialog.ColorDetail = _clDetail
526         SettingDialog.ColorDetailLink = _clDetailLink
527         SettingDialog.ColorDetailBackcolor = _clDetailBackcolor
528         SettingDialog.ColorSelf = _clSelf
529         SettingDialog.ColorAtSelf = _clAtSelf
530         SettingDialog.ColorTarget = _clTarget
531         SettingDialog.ColorAtTarget = _clAtTarget
532         SettingDialog.ColorAtFromTarget = _clAtFromTarget
533         SettingDialog.ColorAtTo = _clAtTo
534         SettingDialog.ColorListBackcolor = _clListBackcolor
535         SettingDialog.ColorInputBackcolor = _clInputBackcolor
536         SettingDialog.ColorInputFont = _clInputFont
537         SettingDialog.FontInputFont = _fntInputFont
538
539         SettingDialog.NameBalloon = _cfgCommon.NameBalloon
540         SettingDialog.PostCtrlEnter = _cfgCommon.PostCtrlEnter
541         SettingDialog.UseAPI = _cfgCommon.UseApi
542         SettingDialog.CountApi = _cfgCommon.CountApi
543         SettingDialog.UsePostMethod = False
544         SettingDialog.HubServer = _cfgCommon.HubServer
545         SettingDialog.BrowserPath = _cfgLocal.BrowserPath
546         SettingDialog.CheckReply = _cfgCommon.CheckReply
547         SettingDialog.PostAndGet = _cfgCommon.PostAndGet
548         SettingDialog.UseRecommendStatus = _cfgLocal.UseRecommendStatus
549         SettingDialog.DispUsername = _cfgCommon.DispUsername
550         SettingDialog.CloseToExit = _cfgCommon.CloseToExit
551         SettingDialog.MinimizeToTray = _cfgCommon.MinimizeToTray
552         SettingDialog.DispLatestPost = _cfgCommon.DispLatestPost
553         SettingDialog.SortOrderLock = _cfgCommon.SortOrderLock
554         SettingDialog.TinyUrlResolve = _cfgCommon.TinyUrlResolve
555
556         SettingDialog.SelectedProxyType = _cfgLocal.ProxyType
557         SettingDialog.ProxyAddress = _cfgLocal.ProxyAddress
558         SettingDialog.ProxyPort = _cfgLocal.ProxyPort
559         SettingDialog.ProxyUser = _cfgLocal.ProxyUser
560         SettingDialog.ProxyPassword = _cfgLocal.ProxyPassword
561
562         SettingDialog.PeriodAdjust = _cfgCommon.PeriodAdjust
563         SettingDialog.StartupVersion = _cfgCommon.StartupVersion
564         SettingDialog.StartupKey = _cfgCommon.StartupKey
565         SettingDialog.StartupFollowers = _cfgCommon.StartupFollowers
566         SettingDialog.StartupAPImodeNoWarning = _cfgCommon.StartupApiModeNoWarning
567         SettingDialog.RestrictFavCheck = _cfgCommon.RestrictFavCheck
568         SettingDialog.AlwaysTop = _cfgCommon.AlwaysTop
569         SettingDialog.UrlConvertAuto = _cfgCommon.UrlConvertAuto
570
571         SettingDialog.OutputzEnabled = _cfgCommon.Outputz
572         SettingDialog.OutputzKey = _cfgCommon.OutputzKey
573         SettingDialog.OutputzUrlmode = _cfgCommon.OutputzUrlMode
574
575         SettingDialog.UseUnreadStyle = _cfgCommon.UseUnreadStyle
576         SettingDialog.DefaultTimeOut = _cfgCommon.DefaultTimeOut
577         SettingDialog.ProtectNotInclude = _cfgCommon.ProtectNotInclude
578         SettingDialog.PlaySound = _cfgCommon.PlaySound
579         SettingDialog.DateTimeFormat = _cfgCommon.DateTimeFormat
580         SettingDialog.LimitBalloon = _cfgCommon.LimitBalloon
581         SettingDialog.AutoShortUrlFirst = _cfgCommon.AutoShortUrlFirst
582         SettingDialog.TabIconDisp = _cfgCommon.TabIconDisp
583         SettingDialog.ReplyIconState = _cfgCommon.ReplyIconState
584         SettingDialog.ReadOwnPost = _cfgCommon.ReadOwnPost
585         SettingDialog.GetFav = _cfgCommon.GetFav
586         SettingDialog.ReadOldPosts = _cfgCommon.ReadOldPosts
587         SettingDialog.UseSsl = _cfgCommon.UseSsl
588         SettingDialog.BitlyUser = _cfgCommon.BilyUser
589         SettingDialog.BitlyPwd = _cfgCommon.BitlyPwd
590         SettingDialog.ShowGrid = _cfgCommon.ShowGrid
591         SettingDialog.Language = _cfgCommon.Language
592         SettingDialog.UseAtIdSupplement = _cfgCommon.UseAtIdSupplement
593         If SettingDialog.UseAtIdSupplement Then
594             AtIdSupl = New AtIdSupplement(SettingAtIdList.Load().AtIdList)
595         End If
596
597         SettingDialog.IsMonospace = _cfgCommon.IsMonospace
598         If SettingDialog.IsMonospace Then
599             detailHtmlFormatHeader = detailHtmlFormatMono1
600             detailHtmlFormatFooter = detailHtmlFormatMono7
601         Else
602             detailHtmlFormatHeader = detailHtmlFormat1
603             detailHtmlFormatFooter = detailHtmlFormat7
604         End If
605         detailHtmlFormatHeader += _fntDetail.Name + detailHtmlFormat2 + _fntDetail.Size.ToString() + detailHtmlFormat3 + _clDetail.R.ToString + "," + _clDetail.G.ToString + "," + _clDetail.B.ToString + detailHtmlFormat4 + _clDetailLink.R.ToString + "," + _clDetailLink.G.ToString + "," + _clDetailLink.B.ToString + detailHtmlFormat5 + _clDetailBackcolor.R.ToString + "," + _clDetailBackcolor.G.ToString + "," + _clDetailBackcolor.B.ToString
606         If SettingDialog.IsMonospace Then
607             detailHtmlFormatHeader += detailHtmlFormatMono6
608         Else
609             detailHtmlFormatHeader += detailHtmlFormat6
610         End If
611         Me.IdeographicSpaceToSpaceToolStripMenuItem.Checked = _cfgCommon.WideSpaceConvert
612
613         Dim statregex As New Regex("^0*")
614         SettingDialog.RecommendStatusText = " [TWNv" + statregex.Replace(fileVersion.Replace(".", ""), "") + "]"
615
616         '書式指定文字列エラーチェック
617         Try
618             If DateTime.Now.ToString(SettingDialog.DateTimeFormat).Length = 0 Then
619                 ' このブロックは絶対に実行されないはず
620                 ' 変換が成功した場合にLengthが0にならない
621                 SettingDialog.DateTimeFormat = "yyyy/MM/dd H:mm:ss"
622             End If
623         Catch ex As FormatException
624             ' FormatExceptionが発生したら初期値を設定 (=yyyy/MM/dd H:mm:ssとみなされる)
625             SettingDialog.DateTimeFormat = "yyyy/MM/dd H:mm:ss"
626         End Try
627
628         Outputz.key = SettingDialog.OutputzKey
629         Outputz.Enabled = SettingDialog.OutputzEnabled
630         Select Case SettingDialog.OutputzUrlmode
631             Case OutputzUrlmode.twittercom
632                 Outputz.url = "http://twitter.com/"
633             Case OutputzUrlmode.twittercomWithUsername
634                 Outputz.url = "http://twitter.com/" + SettingDialog.UserID
635         End Select
636
637         _initial = True
638
639         'ユーザー名、パスワードが未設定なら設定画面を表示(初回起動時など)
640         If _username = "" Or _password = "" Then
641             '設定せずにキャンセルされた場合はプログラム終了
642             If SettingDialog.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
643                 Application.Exit()  '強制終了
644                 Exit Sub
645             End If
646             _username = SettingDialog.UserID
647             _password = SettingDialog.PasswordStr
648             '設定されたが、依然ユーザー名とパスワードが未設定ならプログラム終了
649             If _username = "" Or _password = "" Then
650                 Application.Exit()  '強制終了
651                 Exit Sub
652             End If
653             '新しい設定を反映
654             'フォント&文字色&背景色保持
655             _fntUnread = SettingDialog.FontUnread
656             _clUnread = SettingDialog.ColorUnread
657             _fntReaded = SettingDialog.FontReaded
658             _clReaded = SettingDialog.ColorReaded
659             _clFav = SettingDialog.ColorFav
660             _clOWL = SettingDialog.ColorOWL
661             _clRetweet = SettingDialog.ColorRetweet
662             _fntDetail = SettingDialog.FontDetail
663             _clDetail = SettingDialog.ColorDetail
664             _clDetailLink = SettingDialog.ColorDetailLink
665             _clDetailBackcolor = SettingDialog.ColorDetailBackcolor
666             _clSelf = SettingDialog.ColorSelf
667             _clAtSelf = SettingDialog.ColorAtSelf
668             _clTarget = SettingDialog.ColorTarget
669             _clAtTarget = SettingDialog.ColorAtTarget
670             _clAtFromTarget = SettingDialog.ColorAtFromTarget
671             _clAtTo = SettingDialog.ColorAtTo
672             _clListBackcolor = SettingDialog.ColorListBackcolor
673             _clInputBackcolor = SettingDialog.ColorInputBackcolor
674             _clInputFont = SettingDialog.ColorInputFont
675             _fntInputFont = SettingDialog.FontInputFont
676             _brsForeColorUnread.Dispose()
677             _brsForeColorReaded.Dispose()
678             _brsForeColorFav.Dispose()
679             _brsForeColorOWL.Dispose()
680             _brsForeColorRetweet.Dispose()
681             _brsForeColorUnread = New SolidBrush(_clUnread)
682             _brsForeColorReaded = New SolidBrush(_clReaded)
683             _brsForeColorFav = New SolidBrush(_clFav)
684             _brsForeColorOWL = New SolidBrush(_clOWL)
685             _brsForeColorRetweet = New SolidBrush(_clRetweet)
686             _brsBackColorMine.Dispose()
687             _brsBackColorAt.Dispose()
688             _brsBackColorYou.Dispose()
689             _brsBackColorAtYou.Dispose()
690             _brsBackColorAtFromTarget.Dispose()
691             _brsBackColorAtTo.Dispose()
692             _brsBackColorNone.Dispose()
693             _brsBackColorMine = New SolidBrush(_clSelf)
694             _brsBackColorAt = New SolidBrush(_clAtSelf)
695             _brsBackColorYou = New SolidBrush(_clTarget)
696             _brsBackColorAtYou = New SolidBrush(_clAtTarget)
697             _brsBackColorAtFromTarget = New SolidBrush(_clAtFromTarget)
698             _brsBackColorAtTo = New SolidBrush(_clAtTo)
699             _brsBackColorNone = New SolidBrush(_clListBackcolor)
700
701             If SettingDialog.IsMonospace Then
702                 detailHtmlFormatHeader = detailHtmlFormatMono1
703                 detailHtmlFormatFooter = detailHtmlFormatMono7
704             Else
705                 detailHtmlFormatHeader = detailHtmlFormat1
706                 detailHtmlFormatFooter = detailHtmlFormat7
707             End If
708             detailHtmlFormatHeader += _fntDetail.Name + detailHtmlFormat2 + _fntDetail.Size.ToString() + detailHtmlFormat3 + _clDetail.R.ToString + "," + _clDetail.G.ToString + "," + _clDetail.B.ToString + detailHtmlFormat4 + _clDetailLink.R.ToString + "," + _clDetailLink.G.ToString + "," + _clDetailLink.B.ToString + detailHtmlFormat5 + _clDetailBackcolor.R.ToString + "," + _clDetailBackcolor.G.ToString + "," + _clDetailBackcolor.B.ToString
709             If SettingDialog.IsMonospace Then
710                 detailHtmlFormatHeader += detailHtmlFormatMono6
711             Else
712                 detailHtmlFormatHeader += detailHtmlFormat6
713             End If
714             '他の設定項目は、随時設定画面で保持している値を読み出して使用
715         End If
716
717         'Twitter用通信クラス初期化
718         Twitter.Username = _username
719         Twitter.Password = _password
720         Twitter.SelectedProxyType = SettingDialog.SelectedProxyType
721         Twitter.ProxyAddress = SettingDialog.ProxyAddress
722         Twitter.ProxyPort = SettingDialog.ProxyPort
723         Twitter.ProxyUser = SettingDialog.ProxyUser
724         Twitter.ProxyPassword = SettingDialog.ProxyPassword
725         Twitter.NextThreshold = SettingDialog.NextPageThreshold   '次頁取得閾値
726         Twitter.NextPages = SettingDialog.NextPagesInt    '閾値オーバー時の読み込みページ数(未使用)
727         Twitter.DefaultTimeOut = SettingDialog.DefaultTimeOut
728         Twitter.CountApi = SettingDialog.CountApi
729         Twitter.UseAPI = SettingDialog.UseAPI
730         Twitter.UsePostMethod = False
731         Twitter.HubServer = SettingDialog.HubServer
732         Twitter.RestrictFavCheck = SettingDialog.RestrictFavCheck
733         Twitter.ReadOwnPost = SettingDialog.ReadOwnPost
734         Twitter.UseSsl = SettingDialog.UseSsl
735         Twitter.BitlyId = SettingDialog.BitlyUser
736         Twitter.BitlyKey = SettingDialog.BitlyPwd
737         If IsNetworkAvailable() Then
738             If SettingDialog.StartupFollowers Then
739                 '_waitFollower = True
740                 GetTimeline(WORKERTYPE.Follower, 0, 0)
741             End If
742         End If
743
744         'ウィンドウ設定
745         Me.ClientSize = _cfgLocal.FormSize
746         _mySize = Me.ClientSize                     'サイズ保持(最小化・最大化されたまま終了した場合の対応用)
747         Me.DesktopLocation = _cfgLocal.FormLocation
748         _myLoc = Me.DesktopLocation                        '位置保持(最小化・最大化されたまま終了した場合の対応用)
749         'タイトルバー領域
750         Dim tbarRect As New Rectangle(Me.Location, New Size(_mySize.Width, SystemInformation.CaptionHeight))
751         Dim outOfScreen As Boolean = True
752         If Screen.AllScreens.Length = 1 Then    'ハングするとの報告
753             For Each scr As Screen In Screen.AllScreens
754                 If Not Rectangle.Intersect(tbarRect, scr.Bounds).IsEmpty Then
755                     outOfScreen = False
756                     Exit For
757                 End If
758             Next
759             If outOfScreen Then
760                 Me.DesktopLocation = New Point(0, 0)
761                 _myLoc = Me.DesktopLocation
762             End If
763         End If
764         Me.TopMost = SettingDialog.AlwaysTop
765         _mySpDis = _cfgLocal.SplitterDistance
766         _mySpDis2 = _cfgLocal.StatusTextHeight
767         MultiLineMenuItem.Checked = _cfgLocal.StatusMultiline
768         Me.Tween_ClientSizeChanged(Me, Nothing)
769         PlaySoundMenuItem.Checked = SettingDialog.PlaySound
770         '入力欄
771         StatusText.Font = _fntInputFont
772         StatusText.ForeColor = _clInputFont
773
774         '全新着通知のチェック状態により、Reply&DMの新着通知有効無効切り替え(タブ別設定にするため削除予定)
775         If SettingDialog.UnreadManage = False Then
776             ReadedStripMenuItem.Enabled = False
777             UnreadStripMenuItem.Enabled = False
778         End If
779
780         'タイマー設定
781         'Recent取得間隔
782         If SettingDialog.TimelinePeriodInt > 0 Then
783             TimerTimeline.Interval = SettingDialog.TimelinePeriodInt * 1000
784         Else
785             TimerTimeline.Interval = 600000
786         End If
787         'Reply取得間隔
788         If SettingDialog.ReplyPeriodInt > 0 Then
789             TimerReply.Interval = SettingDialog.ReplyPeriodInt * 1000
790         Else
791             TimerReply.Interval = 6000000
792         End If
793         'DM取得間隔
794         If SettingDialog.DMPeriodInt > 0 Then
795             TimerDM.Interval = SettingDialog.DMPeriodInt * 1000
796         Else
797             TimerDM.Interval = 6000000
798         End If
799         '更新中アイコンアニメーション間隔
800         TimerRefreshIcon.Interval = 85
801         TimerRefreshIcon.Enabled = True
802
803         '状態表示部の初期化(画面右下)
804         StatusLabel.Text = ""
805         '文字カウンタ初期化
806         lblLen.Text = GetRestStatusCount(True, False).ToString()
807
808         If SettingDialog.StartupKey Then
809             Twitter.GetWedata()
810         End If
811
812         ''''''''''''''''''''''''''''''''''''''''
813         _statuses.SortOrder = DirectCast(_cfgCommon.SortOrder, System.Windows.Forms.SortOrder)
814         Dim mode As IdComparerClass.ComparerMode
815         Select Case _cfgCommon.SortColumn
816             Case 0, 5, 6    '0:アイコン,5:未読マーク,6:プロテクト・フィルターマーク
817                 'ソートしない
818                 mode = IdComparerClass.ComparerMode.Id  'Idソートに読み替え
819             Case 1  'ニックネーム
820                 mode = IdComparerClass.ComparerMode.Nickname
821             Case 2  '本文
822                 mode = IdComparerClass.ComparerMode.Data
823             Case 3  '時刻=発言Id
824                 mode = IdComparerClass.ComparerMode.Id
825             Case 4  '名前
826                 mode = IdComparerClass.ComparerMode.Name
827             Case 7  'Source
828                 mode = IdComparerClass.ComparerMode.Source
829         End Select
830         _statuses.SortMode = mode
831         ''''''''''''''''''''''''''''''''''''''''
832
833         Select Case SettingDialog.IconSz
834             Case IconSizes.IconNone
835                 _iconSz = 0
836             Case IconSizes.Icon16
837                 _iconSz = 16
838             Case IconSizes.Icon24
839                 _iconSz = 26
840             Case IconSizes.Icon48
841                 _iconSz = 48
842             Case IconSizes.Icon48_2
843                 _iconSz = 48
844                 _iconCol = True
845         End Select
846         If _iconSz = 0 Then
847             Twitter.GetIcon = False
848         Else
849             Twitter.GetIcon = True
850             Twitter.IconSize = _iconSz
851         End If
852         Twitter.TinyUrlResolve = SettingDialog.TinyUrlResolve
853
854         '発言詳細部アイコンをリストアイコンにサイズ変更
855         Dim sz As Integer = _iconSz
856         If _iconSz = 0 Then
857             sz = 16
858         End If
859         TIconSmallList = New ImageList
860         TIconSmallList.ImageSize = New Size(sz, sz)
861         TIconSmallList.ColorDepth = ColorDepth.Depth32Bit
862         '発言詳細部のアイコンリスト作成
863         TIconDic = New Dictionary(Of String, Image)
864
865         Twitter.ListIcon = TIconSmallList
866         Twitter.DetailIcon = TIconDic
867
868         StatusLabel.Text = My.Resources.Form1_LoadText1       '画面右下の状態表示を変更
869         StatusLabelUrl.Text = ""            '画面左下のリンク先URL表示部を初期化
870         NameLabel.Text = ""                 '発言詳細部名前ラベル初期化
871         DateTimeLabel.Text = ""             '発言詳細部日時ラベル初期化
872
873         '<<<<<<<<タブ関連>>>>>>>
874         'デフォルトタブの存在チェック、ない場合には追加
875         If _statuses.GetTabByType(TabUsageType.Home) Is Nothing Then
876             If Not _statuses.Tabs.ContainsKey(DEFAULTTAB.RECENT) Then
877                 _statuses.AddTab(DEFAULTTAB.RECENT, TabUsageType.Home)
878             Else
879                 _statuses.Tabs(DEFAULTTAB.RECENT).TabType = TabUsageType.Home
880             End If
881         End If
882         If _statuses.GetTabByType(TabUsageType.Mentions) Is Nothing Then
883             If Not _statuses.Tabs.ContainsKey(DEFAULTTAB.REPLY) Then
884                 _statuses.AddTab(DEFAULTTAB.REPLY, TabUsageType.Mentions)
885             Else
886                 _statuses.Tabs(DEFAULTTAB.REPLY).TabType = TabUsageType.Mentions
887             End If
888         End If
889         If _statuses.GetTabByType(TabUsageType.DirectMessage) Is Nothing Then
890             If Not _statuses.Tabs.ContainsKey(DEFAULTTAB.DM) Then
891                 _statuses.AddTab(DEFAULTTAB.DM, TabUsageType.DirectMessage)
892             Else
893                 _statuses.Tabs(DEFAULTTAB.DM).TabType = TabUsageType.DirectMessage
894             End If
895         End If
896         If _statuses.GetTabByType(TabUsageType.Favorites) Is Nothing Then
897             If Not _statuses.Tabs.ContainsKey(DEFAULTTAB.FAV) Then
898                 _statuses.AddTab(DEFAULTTAB.FAV, TabUsageType.Favorites)
899             Else
900                 _statuses.Tabs(DEFAULTTAB.FAV).TabType = TabUsageType.Favorites
901             End If
902         End If
903         For Each tn As String In _statuses.Tabs.Keys
904             If _statuses.Tabs(tn).TabType = TabUsageType.Undefined Then
905                 _statuses.Tabs(tn).TabType = TabUsageType.UserDefined
906             End If
907             If Not AddNewTab(tn, True, _statuses.Tabs(tn).TabType) Then Throw New Exception("タブ作成エラー")
908         Next
909
910         JumpUnreadMenuItem.ShortcutKeyDisplayString = "Space"
911         CopySTOTMenuItem.ShortcutKeyDisplayString = "Ctrl+C"
912         CopyURLMenuItem.ShortcutKeyDisplayString = "Ctrl+Shift+C"
913         'MenuItemSubSearch.ShortcutKeyDisplayString = "/"
914         'ReadedStripMenuItem.ShortcutKeyDisplayString = "B"
915         'UnreadStripMenuItem.ShortcutKeyDisplayString = "Shift+B"
916
917         AddHandler My.Computer.Network.NetworkAvailabilityChanged, AddressOf Network_NetworkAvailabilityChanged
918         If SettingDialog.MinimizeToTray = False OrElse Me.WindowState <> FormWindowState.Minimized Then
919             Me.Visible = True
920         End If
921         _curTab = ListTab.SelectedTab
922         _curItemIndex = -1
923         _curList = DirectCast(_curTab.Tag, DetailsListView)
924         SetMainWindowTitle()
925         SetNotifyIconText()
926
927         If SettingDialog.TabIconDisp Then
928             ListTab.DrawMode = TabDrawMode.Normal
929         Else
930             ListTab.DrawMode = TabDrawMode.OwnerDrawFixed
931             AddHandler ListTab.DrawItem, AddressOf ListTab_DrawItem
932             ListTab.ImageList = Nothing
933         End If
934
935         TimerColorize.Interval = 200
936         TimerColorize.Start()
937         _ignoreConfigSave = False
938         SaveConfigsAll(False)
939     End Sub
940
941     Private Sub ListTab_DrawItem( _
942             ByVal sender As Object, ByVal e As DrawItemEventArgs)
943         Dim txt As String
944         Try
945             txt = ListTab.TabPages(e.Index).Text
946         Catch ex As Exception
947             Exit Sub
948         End Try
949
950         e.Graphics.FillRectangle(System.Drawing.SystemBrushes.Control, e.Bounds)
951         If e.State = DrawItemState.Selected Then
952             e.DrawFocusRectangle()
953         End If
954         Dim fore As Brush
955         Try
956             If _statuses.Tabs(txt).UnreadCount > 0 Then
957                 fore = Brushes.Red
958             Else
959                 fore = System.Drawing.SystemBrushes.ControlText
960             End If
961         Catch ex As Exception
962             fore = System.Drawing.SystemBrushes.ControlText
963         End Try
964         e.Graphics.DrawString(txt, e.Font, fore, e.Bounds, sfTab)
965         fore.Dispose()
966     End Sub
967
968     Private Function LoadOldConfig() As Boolean
969         Dim needToSave As Boolean = False
970         _cfgCommon = SettingCommon.Load()
971         _cfgLocal = SettingLocal.Load()
972         If _cfgCommon.TabList.Count > 0 Then
973             For Each tabName As String In _cfgCommon.TabList
974                 _statuses.Tabs.Add(tabName, SettingTab.Load(tabName).Tab)
975                 If tabName <> ReplaceInvalidFilename(tabName) Then
976                     Dim tb As TabClass = _statuses.Tabs(tabName)
977                     _statuses.RemoveTab(tabName)
978                     tb.TabName = ReplaceInvalidFilename(tabName)
979                     _statuses.Tabs.Add(ReplaceInvalidFilename(tabName), tb)
980                     Dim tabSetting As New SettingTab
981                     tabSetting.Tab = tb
982                     tabSetting.Save()
983                     needToSave = True
984                 End If
985             Next
986         Else
987             _statuses.AddTab(DEFAULTTAB.RECENT, TabUsageType.Home)
988             _statuses.AddTab(DEFAULTTAB.REPLY, TabUsageType.Mentions)
989             _statuses.AddTab(DEFAULTTAB.DM, TabUsageType.DirectMessage)
990             _statuses.AddTab(DEFAULTTAB.FAV, TabUsageType.Favorites)
991         End If
992         If needToSave Then
993             _cfgCommon.TabList.Clear()
994             For Each tabName As String In _statuses.Tabs.Keys
995                 _cfgCommon.TabList.Add(tabName)
996             Next
997             _cfgCommon.Save()
998         End If
999
1000         If System.IO.File.Exists(SettingCommon.GetSettingFilePath("")) Then
1001             Return True
1002         Else
1003             Return False
1004         End If
1005     End Function
1006
1007     Private Sub LoadConfig()
1008         Dim needToSave As Boolean = False
1009         _cfgCommon = SettingCommon.Load()
1010         _cfgLocal = SettingLocal.Load()
1011         Dim tabs As List(Of TabClass) = SettingTabs.Load().Tabs
1012         For Each tb As TabClass In tabs
1013             _statuses.Tabs.Add(tb.TabName, tb)
1014         Next
1015         If _statuses.Tabs.Count = 0 Then
1016             _statuses.AddTab(DEFAULTTAB.RECENT, TabUsageType.Home)
1017             _statuses.AddTab(DEFAULTTAB.REPLY, TabUsageType.Mentions)
1018             _statuses.AddTab(DEFAULTTAB.DM, TabUsageType.DirectMessage)
1019             _statuses.AddTab(DEFAULTTAB.FAV, TabUsageType.Favorites)
1020         End If
1021     End Sub
1022
1023     Private Sub ConvertConfig()
1024         '新タブ設定ファイル存在チェック
1025         If System.IO.File.Exists(SettingTabs.GetSettingFilePath("")) Then
1026             LoadConfig()
1027             Exit Sub
1028         End If
1029         If LoadOldConfig() Then Exit Sub
1030
1031         '_cfg = SettingToConfig.Load()
1032         'If _cfg Is Nothing Then Exit Sub
1033
1034         ''新設定ファイルへ変換
1035         ''新しくエントリを増設する場合はここに書く必要はない
1036         '_cfgCommon.AlwaysTop = _cfg.AlwaysTop
1037         '_cfgCommon.AutoShortUrlFirst = _cfg.AutoShortUrlFirst
1038         '_cfgLocal.BrowserPath = _cfg.BrowserPath
1039         '_cfgCommon.CheckReply = _cfg.CheckReply
1040         '_cfgCommon.CloseToExit = _cfg.CloseToExit
1041         '_cfgLocal.ColorAtFromTarget = _cfg.ColorAtFromTarget
1042         '_cfgLocal.ColorAtSelf = _cfg.ColorAtSelf
1043         '_cfgLocal.ColorAtTarget = _cfg.ColorAtTarget
1044         '_cfgLocal.ColorFav = _cfg.ColorFav
1045         '_cfgLocal.ColorOWL = _cfg.ColorOWL
1046         '_cfgLocal.ColorRead = _cfg.ColorRead
1047         '_cfgLocal.ColorSelf = _cfg.ColorSelf
1048         '_cfgLocal.ColorTarget = _cfg.ColorTarget
1049         '_cfgLocal.ColorUnread = _cfg.ColorUnread
1050         '_cfgLocal.ColorInputBackcolor = _cfg.ColorInputBackcolor
1051         '_cfgLocal.ColorInputFont = _cfg.ColorInputFont
1052         '_cfgCommon.CountApi = _cfg.CountApi
1053         '_cfgCommon.CultureCode = _cfg.cultureCode
1054         '_cfgCommon.DateTimeFormat = _cfg.DateTimeFormat
1055         '_cfgCommon.DefaultTimeOut = _cfg.DefaultTimeOut
1056         '_cfgCommon.DispLatestPost = _cfg.DispLatestPost
1057         '_cfgLocal.DisplayIndex1 = _cfg.DisplayIndex1
1058         '_cfgLocal.DisplayIndex2 = _cfg.DisplayIndex2
1059         '_cfgLocal.DisplayIndex3 = _cfg.DisplayIndex3
1060         '_cfgLocal.DisplayIndex4 = _cfg.DisplayIndex4
1061         '_cfgLocal.DisplayIndex5 = _cfg.DisplayIndex5
1062         '_cfgLocal.DisplayIndex6 = _cfg.DisplayIndex6
1063         '_cfgLocal.DisplayIndex7 = _cfg.DisplayIndex7
1064         '_cfgLocal.DisplayIndex8 = _cfg.DisplayIndex8
1065         '_cfgCommon.DispUsername = _cfg.DispUsername
1066         '_cfgCommon.DMPeriod = _cfg.DMPeriod
1067         '_cfgLocal.FontDetail = _cfg.FontDetail
1068         '_cfgLocal.FontRead = _cfg.FontRead
1069         '_cfgLocal.FontUnread = _cfg.FontUnread
1070         '_cfgLocal.FontInputFont = _cfg.FontInputFont
1071         '_cfgLocal.FormLocation = _cfg.FormLocation
1072         '_cfgLocal.FormSize = _cfg.FormSize
1073         '_cfgCommon.HubServer = _cfg.HubServer
1074         '_cfgCommon.IconSize = _cfg.IconSize
1075         '_cfgCommon.LimitBalloon = _cfg.LimitBalloon
1076         '_cfgCommon.ListLock = _cfg.ListLock
1077         '_cfgCommon.MaxPostNum = _cfg.MaxPostNum
1078         '_cfgCommon.MinimizeToTray = _cfg.MinimizeToTray
1079         '_cfgCommon.NameBalloon = _cfg.NameBalloon
1080         '_cfgCommon.NewAllPop = _cfg.NewAllPop
1081         '_cfgCommon.NextPages = _cfg.NextPages
1082         '_cfgCommon.NextPageThreshold = _cfg.NextPageThreshold
1083         '_cfgCommon.OneWayLove = _cfg.OneWayLove
1084         '_cfgCommon.Outputz = _cfg.Outputz
1085         '_cfgCommon.OutputzKey = _cfg.OutputzKey
1086         '_cfgCommon.OutputzUrlMode = _cfg.OutputzUrlmode
1087         '_cfgCommon.Password = _cfg.Password
1088         '_cfgCommon.PeriodAdjust = _cfg.PeriodAdjust
1089         '_cfgCommon.PlaySound = _cfg.PlaySound
1090         '_cfgCommon.PostAndGet = _cfg.PostAndGet
1091         '_cfgCommon.PostCtrlEnter = _cfg.PostCtrlEnter
1092         '_cfgCommon.ProtectNotInclude = _cfg.ProtectNotInclude
1093         '_cfgLocal.ProxyAddress = _cfg.ProxyAddress
1094         '_cfgLocal.ProxyPassword = _cfg.ProxyPassword
1095         '_cfgLocal.ProxyPort = _cfg.ProxyPort
1096         '_cfgLocal.ProxyType = _cfg.ProxyType
1097         '_cfgLocal.ProxyUser = _cfg.ProxyUser
1098         '_cfgCommon.Read = _cfg.Read
1099         '_cfgCommon.ReadPages = _cfg.ReadPages
1100         '_cfgCommon.ReadPagesDM = _cfg.ReadPagesDM
1101         '_cfgCommon.ReadPagesReply = _cfg.ReadPagesReply
1102         '_cfgCommon.RestrictFavCheck = _cfg.RestrictFavCheck
1103         '_cfgCommon.SortColumn = _cfg.SortColumn
1104         '_cfgCommon.SortOrder = _cfg.SortOrder
1105         '_cfgCommon.SortOrderLock = _cfg.SortOrderLock
1106         '_cfgLocal.SplitterDistance = _cfg.SplitterDistance
1107         '_cfgCommon.StartupFollowers = _cfg.StartupFollowers
1108         '_cfgCommon.StartupKey = _cfg.StartupKey
1109         '_cfgCommon.StartupVersion = _cfg.StartupVersion
1110         '_cfgCommon.StartupApiModeNoWarning = _cfg.StartupAPImodeNoWarning
1111         '_cfgLocal.StatusMultiline = _cfg.StatusMultiline
1112         '_cfgLocal.StatusText = _cfg.StatusText
1113         '_cfgLocal.StatusTextHeight = _cfg.StatusTextHeight
1114
1115         'For Each item As KeyValuePair(Of String, TabClass) In _cfg.Tabs
1116         '    Dim tabSetting As New SettingTab
1117         '    item.Value.TabName = ReplaceInvalidFilename(item.Value.TabName)
1118         '    tabSetting.Tab = item.Value
1119         '    tabSetting.Save()
1120         '    _cfgCommon.TabList.Add(ReplaceInvalidFilename(item.Key))
1121         '    If Not _statuses.Tabs.ContainsKey(tabSetting.Tab.TabName) Then
1122         '        _statuses.Tabs.Add(tabSetting.Tab.TabName, tabSetting.Tab)
1123         '    ElseIf tabSetting.Tab.TabName = DEFAULTTAB.REPLY Then
1124         '        _statuses.Tabs(DEFAULTTAB.REPLY) = tabSetting.Tab
1125         '    End If
1126         'Next
1127         '_cfgCommon.TimelinePeriod = _cfg.TimelinePeriod
1128         '_cfgCommon.TinyUrlResolve = _cfg.TinyURLResolve
1129         '_cfgCommon.UnreadManage = _cfg.UnreadManage
1130         '_cfgCommon.UrlConvertAuto = _cfg.UrlConvertAuto
1131         '_cfgCommon.UseApi = _cfg.UseAPI
1132         '_cfgCommon.UsePostMethod = _cfg.UsePostMethod
1133         '_cfgLocal.UseRecommendStatus = _cfg.UseRecommendStatus
1134         '_cfgCommon.UserName = _cfg.UserName
1135         '_cfgCommon.UseUnreadStyle = _cfg.UseUnreadStyle
1136         '_cfgLocal.Width1 = _cfg.Width1
1137         '_cfgLocal.Width2 = _cfg.Width2
1138         '_cfgLocal.Width3 = _cfg.Width3
1139         '_cfgLocal.Width4 = _cfg.Width4
1140         '_cfgLocal.Width5 = _cfg.Width5
1141         '_cfgLocal.Width6 = _cfg.Width6
1142         '_cfgLocal.Width7 = _cfg.Width7
1143         '_cfgLocal.Width8 = _cfg.Width8
1144         ''念のため保存
1145         '_cfgCommon.Save()
1146         '_cfgLocal.Save()
1147     End Sub
1148
1149     Private Sub Network_NetworkAvailabilityChanged(ByVal sender As Object, ByVal e As Devices.NetworkAvailableEventArgs)
1150         If e.IsNetworkAvailable Then
1151             Dim args As New GetWorkerArg()
1152             PostButton.Enabled = True
1153             FavAddToolStripMenuItem.Enabled = True
1154             FavRemoveToolStripMenuItem.Enabled = True
1155             MoveToHomeToolStripMenuItem.Enabled = True
1156             MoveToFavToolStripMenuItem.Enabled = True
1157             DeleteStripMenuItem.Enabled = True
1158             RefreshStripMenuItem.Enabled = True
1159             _myStatusOnline = True
1160             If Not _initial Then
1161                 'If SettingDialog.DMPeriodInt > 0 Then TimerDM.Enabled = True
1162                 'If SettingDialog.TimelinePeriodInt > 0 Then TimerTimeline.Enabled = True
1163                 'If SettingDialog.ReplyPeriodInt > 0 Then TimerReply.Enabled = True
1164             Else
1165                 GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0)
1166             End If
1167         Else
1168             _myStatusOnline = False
1169             PostButton.Enabled = False
1170             FavAddToolStripMenuItem.Enabled = False
1171             FavRemoveToolStripMenuItem.Enabled = False
1172             MoveToHomeToolStripMenuItem.Enabled = False
1173             MoveToFavToolStripMenuItem.Enabled = False
1174             DeleteStripMenuItem.Enabled = False
1175             RefreshStripMenuItem.Enabled = False
1176         End If
1177     End Sub
1178
1179     Private Sub TimerTimeline_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerTimeline.Tick
1180
1181         If Not IsNetworkAvailable() Then Exit Sub
1182
1183         GetTimeline(WORKERTYPE.Timeline, 1, 0)
1184     End Sub
1185
1186     Private Sub TimerDM_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerDM.Tick
1187         GC.Collect()
1188
1189         If Not IsNetworkAvailable() Then Exit Sub
1190
1191         GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0)
1192     End Sub
1193
1194     Private Sub TimerReply_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerReply.Tick
1195         If Not IsNetworkAvailable() Then Exit Sub
1196
1197         GetTimeline(WORKERTYPE.Reply, 1, 0)
1198     End Sub
1199
1200     Private Sub RefreshTimeline()
1201         'スクロール制御準備
1202         Dim smode As Integer = -1    '-1:制御しない,-2:最新へ,その他:topitem使用
1203         Dim topId As Long = GetScrollPos(smode)
1204         Dim befCnt As Integer = _curList.VirtualListSize
1205
1206         '現在の選択状態を退避
1207         Dim selId As New Dictionary(Of String, Long())
1208         Dim focusedId As New Dictionary(Of String, Long)
1209         SaveSelectedStatus(selId, focusedId)
1210
1211         '更新確定
1212         Dim notifyPosts() As PostClass = Nothing
1213         Dim soundFile As String = ""
1214         Dim addCount As Integer = 0
1215         addCount = _statuses.SubmitUpdate(soundFile, notifyPosts)
1216
1217         If _endingFlag Then Exit Sub
1218
1219         'リストに反映&選択状態復元
1220         Try
1221             For Each tab As TabPage In ListTab.TabPages
1222                 Dim lst As DetailsListView = DirectCast(tab.Tag, DetailsListView)
1223                 Dim tabInfo As TabClass = _statuses.Tabs(tab.Text)
1224                 lst.BeginUpdate()
1225                 If lst.VirtualListSize <> tabInfo.AllCount Then
1226                     If lst.Equals(_curList) Then
1227                         _itemCache = Nothing
1228                         _postCache = Nothing
1229                     End If
1230                     lst.VirtualListSize = tabInfo.AllCount 'リスト件数更新
1231                     Me.SelectListItem(lst, _
1232                                       _statuses.IndexOf(tab.Text, selId(tab.Text)), _
1233                                       _statuses.IndexOf(tab.Text, focusedId(tab.Text)))
1234                 End If
1235                 lst.EndUpdate()
1236                 If tabInfo.UnreadCount > 0 Then
1237                     If SettingDialog.TabIconDisp Then
1238                         If tab.ImageIndex = -1 Then tab.ImageIndex = 0 'タブアイコン
1239                     End If
1240                 End If
1241             Next
1242             If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
1243         Catch ex As Exception
1244             'ex.Data("Msg") = "Ref1, UseAPI=" + SettingDialog.UseAPI.ToString
1245             'Throw
1246         End Try
1247
1248         'スクロール制御後処理
1249         Try
1250             If befCnt <> _curList.VirtualListSize Then
1251                 Select Case smode
1252                     Case -3
1253                         '最上行
1254                         _curList.EnsureVisible(0)
1255                     Case -2
1256                         '最下行へ
1257                         _curList.EnsureVisible(_curList.VirtualListSize - 1)
1258                     Case -1
1259                         '制御しない
1260                     Case Else
1261                         '表示位置キープ
1262                         If _curList.VirtualListSize > 0 Then
1263                             _curList.EnsureVisible(_curList.VirtualListSize - 1)
1264                             _curList.EnsureVisible(_statuses.IndexOf(_curTab.Text, topId))
1265                         End If
1266                 End Select
1267             End If
1268         Catch ex As Exception
1269             ex.Data("Msg") = "Ref2, UseAPI=" + SettingDialog.UseAPI.ToString
1270             Throw
1271         End Try
1272
1273         '新着通知
1274         NotifyNewPosts(notifyPosts, soundFile, addCount)
1275
1276         SetMainWindowTitle()
1277         If Not StatusLabelUrl.Text.StartsWith("http") Then SetStatusLabel()
1278     End Sub
1279
1280     Private Function GetScrollPos(ByRef smode As Integer) As Long
1281         Dim topId As Long = -1
1282         If _curList IsNot Nothing AndAlso _curTab IsNot Nothing AndAlso _curList.VirtualListSize > 0 Then
1283             If _statuses.SortMode = IdComparerClass.ComparerMode.Id Then
1284                 If _statuses.SortOrder = SortOrder.Ascending Then
1285                     'Id昇順
1286                     If ListLockMenuItem.Checked Then
1287                         '制御しない
1288                         'smode = -1
1289                         '現在表示位置へ強制スクロール
1290                         topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index)
1291                         smode = 0
1292                     Else
1293                         '最下行が表示されていたら、最下行へ強制スクロール。最下行が表示されていなかったら制御しない
1294                         Dim _item As ListViewItem
1295                         _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1)   '一番下
1296                         If _item Is Nothing Then _item = _curList.Items(_curList.Items.Count - 1)
1297                         If _item.Index = _curList.Items.Count - 1 Then
1298                             smode = -2
1299                         Else
1300                             'smode = -1
1301                             topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index)
1302                             smode = 0
1303                         End If
1304                     End If
1305                 Else
1306                     'Id降順
1307                     If ListLockMenuItem.Checked Then
1308                         '現在表示位置へ強制スクロール
1309                         topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index)
1310                         smode = 0
1311                     Else
1312                         '最上行が表示されていたら、制御しない。最上行が表示されていなかったら、現在表示位置へ強制スクロール
1313                         Dim _item As ListViewItem
1314
1315                         _item = _curList.GetItemAt(0, 10)     '一番上
1316                         If _item Is Nothing Then _item = _curList.Items(0)
1317                         If _item.Index = 0 Then
1318                             smode = -3  '最上行
1319                         Else
1320                             topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index)
1321                             smode = 0
1322                         End If
1323                     End If
1324                 End If
1325             Else
1326                 '現在表示位置へ強制スクロール
1327                 topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index)
1328                 smode = 0
1329             End If
1330         Else
1331             smode = -1
1332         End If
1333         Return topId
1334     End Function
1335
1336     Private Sub SaveSelectedStatus(ByVal selId As Dictionary(Of String, Long()), ByVal focusedId As Dictionary(Of String, Long))
1337         If _endingFlag Then Exit Sub
1338         For Each tab As TabPage In ListTab.TabPages
1339             Dim lst As DetailsListView = DirectCast(tab.Tag, DetailsListView)
1340             If lst.SelectedIndices.Count > 0 AndAlso lst.SelectedIndices.Count < 31 Then
1341                 selId.Add(tab.Text, _statuses.GetId(tab.Text, lst.SelectedIndices))
1342             Else
1343                 selId.Add(tab.Text, New Long(0) {-1})
1344             End If
1345             If lst.FocusedItem IsNot Nothing Then
1346                 focusedId.Add(tab.Text, _statuses.GetId(tab.Text, lst.FocusedItem.Index))
1347             Else
1348                 focusedId.Add(tab.Text, -1)
1349             End If
1350         Next
1351
1352     End Sub
1353
1354     Private Sub NotifyNewPosts(ByVal notifyPosts() As PostClass, ByVal soundFile As String, ByVal addCount As Integer)
1355         '新着通知
1356         If (NewPostPopMenuItem.Checked AndAlso _
1357                notifyPosts IsNot Nothing AndAlso notifyPosts.Length > 0 AndAlso _
1358                Not _initial AndAlso _
1359                ((SettingDialog.LimitBalloon AndAlso _
1360                  (Me.WindowState = FormWindowState.Minimized OrElse Not Me.Visible OrElse Form.ActiveForm Is Nothing)) _
1361                 OrElse Not SettingDialog.LimitBalloon)) AndAlso Not IsScreenSaverRunning() Then
1362             Dim sb As New StringBuilder
1363             Dim reply As Boolean = False
1364             Dim dm As Boolean = False
1365             For Each post As PostClass In notifyPosts
1366                 If post.IsReply Then reply = True
1367                 If post.IsDm Then dm = True
1368                 If sb.Length > 0 Then sb.Append(System.Environment.NewLine)
1369                 Select Case SettingDialog.NameBalloon
1370                     Case NameBalloonEnum.UserID
1371                         sb.Append(post.Name).Append(" : ")
1372                     Case NameBalloonEnum.NickName
1373                         sb.Append(post.Nickname).Append(" : ")
1374                 End Select
1375                 sb.Append(post.Data)
1376             Next
1377             If SettingDialog.DispUsername Then NotifyIcon1.BalloonTipTitle = _username + " - " Else NotifyIcon1.BalloonTipTitle = ""
1378             If dm Then
1379                 NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning
1380                 NotifyIcon1.BalloonTipTitle += "Tween [DM] " + My.Resources.RefreshDirectMessageText1 + " " + addCount.ToString() + My.Resources.RefreshDirectMessageText2
1381             ElseIf reply Then
1382                 NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning
1383                 NotifyIcon1.BalloonTipTitle += "Tween [Reply!] " + My.Resources.RefreshTimelineText1 + " " + addCount.ToString() + My.Resources.RefreshTimelineText2
1384             Else
1385                 NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info
1386                 NotifyIcon1.BalloonTipTitle += "Tween " + My.Resources.RefreshTimelineText1 + " " + addCount.ToString() + My.Resources.RefreshTimelineText2
1387             End If
1388             Dim bText As String = sb.ToString
1389             If String.IsNullOrEmpty(bText) Then Exit Sub
1390             NotifyIcon1.BalloonTipText = sb.ToString()
1391             NotifyIcon1.ShowBalloonTip(500)
1392         End If
1393
1394         'サウンド再生
1395         If Not _initial AndAlso SettingDialog.PlaySound AndAlso soundFile <> "" Then
1396             Try
1397                 My.Computer.Audio.Play(Path.Combine(My.Application.Info.DirectoryPath.ToString(), soundFile), AudioPlayMode.Background)
1398             Catch ex As Exception
1399
1400             End Try
1401         End If
1402     End Sub
1403
1404     'Private Sub Mylist_Scrolled(ByVal sender As Object, ByVal e As System.EventArgs)
1405     '    'TimerColorize.Stop()
1406     '    'TimerColorize.Start()
1407     'End Sub
1408
1409     Private Sub MyList_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
1410         If _curList.SelectedIndices.Count <> 1 Then Exit Sub
1411         'If _curList.SelectedIndices.Count = 0 Then Exit Sub
1412
1413         _curItemIndex = _curList.SelectedIndices(0)
1414         _curPost = GetCurTabPost(_curItemIndex)
1415         If SettingDialog.UnreadManage Then _statuses.SetRead(True, _curTab.Text, _curItemIndex)
1416         'MyList.RedrawItems(MyList.SelectedIndices(0), MyList.SelectedIndices(0), False)   'RetrieveVirtualItemが発生することを期待
1417         'キャッシュの書き換え
1418         ChangeCacheStyleRead(True, _curItemIndex, _curTab)   '既読へ(フォント、文字色)
1419
1420         'ColorizeList(-1)    '全キャッシュ更新(背景色)
1421         'DispSelectedPost()
1422         ColorizeList()
1423         TimerColorize.Stop()
1424         TimerColorize.Start()
1425         'cMode = 1
1426     End Sub
1427
1428     Private Sub ChangeCacheStyleRead(ByVal Read As Boolean, ByVal Index As Integer, ByVal Tab As TabPage)
1429         'Read:True=既読 False=未読
1430         '未読管理していなかったら既読として扱う
1431         If Not _statuses.Tabs(_curTab.Text).UnreadManage OrElse _
1432            Not SettingDialog.UnreadManage Then Read = True
1433
1434         '対象の特定
1435         Dim itm As ListViewItem
1436         Dim post As PostClass
1437         If Tab.Equals(_curTab) AndAlso _itemCache IsNot Nothing AndAlso Index >= _itemCacheIndex AndAlso Index < _itemCacheIndex + _itemCache.Length Then
1438             itm = _itemCache(Index - _itemCacheIndex)
1439             post = _postCache(Index - _itemCacheIndex)
1440         Else
1441             itm = DirectCast(Tab.Tag, DetailsListView).Items(Index)
1442             post = _statuses.Item(Tab.Text, Index)
1443         End If
1444
1445         ChangeItemStyleRead(Read, itm, post, DirectCast(Tab.Tag, DetailsListView))
1446     End Sub
1447
1448     Private Sub ChangeItemStyleRead(ByVal Read As Boolean, ByVal Item As ListViewItem, ByVal Post As PostClass, ByVal DList As DetailsListView)
1449         Dim fnt As Font
1450         'フォント
1451         If Read Then
1452             fnt = _fntReaded
1453             Item.SubItems(5).Text = ""
1454         Else
1455             fnt = _fntUnread
1456             Item.SubItems(5).Text = "★"
1457         End If
1458         '文字色
1459         Dim cl As Color
1460         If Post.IsFav Then
1461             cl = _clFav
1462         ElseIf Post.RetweetedId > 0 Then
1463             cl = _clRetweet
1464         ElseIf Post.IsOwl AndAlso (Post.IsDm OrElse SettingDialog.OneWayLove) Then
1465             cl = _clOWL
1466         ElseIf Read OrElse Not SettingDialog.UseUnreadStyle Then
1467             cl = _clReaded
1468         Else
1469             cl = _clUnread
1470         End If
1471         If DList Is Nothing OrElse Item.Index = -1 Then
1472             Item.ForeColor = cl
1473             If SettingDialog.UseUnreadStyle Then
1474                 Item.Font = fnt
1475             End If
1476         Else
1477             DList.Update()
1478             If SettingDialog.UseUnreadStyle Then
1479                 DList.ChangeItemFontAndColor(Item.Index, cl, fnt)
1480             Else
1481                 DList.ChangeItemForeColor(Item.Index, cl)
1482             End If
1483             'If _itemCache IsNot Nothing Then DList.RedrawItems(_itemCacheIndex, _itemCacheIndex + _itemCache.Length - 1, False)
1484         End If
1485     End Sub
1486
1487     Private Sub ColorizeList()
1488         'Index:更新対象のListviewItem.Index。Colorを返す。
1489         '-1は全キャッシュ。Colorは返さない(ダミーを戻す)
1490         Dim _post As PostClass
1491         If _anchorFlag Then
1492             _post = _anchorPost
1493         Else
1494             _post = _curPost
1495         End If
1496
1497         If _itemCache Is Nothing Then Exit Sub
1498
1499         'For cnt As Integer = 0 To _itemCache.Length - 1
1500         '    If Not _postCache(cnt).IsRead AndAlso SettingDialog.UnreadManage AndAlso _statuses.Tabs(_curTab.Text).UnreadManage Then
1501         '        _itemCache(cnt).Font = _fntUnread
1502         '    Else
1503         '        _itemCache(cnt).Font = _fntReaded
1504         '    End If
1505         'Next
1506
1507         If _post Is Nothing Then Exit Sub
1508
1509         Try
1510             For cnt As Integer = 0 To _itemCache.Length - 1
1511                 '_itemCache(cnt).BackColor = JudgeColor(_post, _postCache(cnt))
1512                 _curList.ChangeItemBackColor(_itemCacheIndex + cnt, JudgeColor(_post, _postCache(cnt)))
1513             Next
1514         Catch ex As Exception
1515         End Try
1516     End Sub
1517
1518     Private Sub ColorizeList(ByVal Item As ListViewItem, ByVal Index As Integer)
1519         'Index:更新対象のListviewItem.Index。Colorを返す。
1520         '-1は全キャッシュ。Colorは返さない(ダミーを戻す)
1521         Dim _post As PostClass
1522         If _anchorFlag Then
1523             _post = _anchorPost
1524         Else
1525             _post = _curPost
1526         End If
1527
1528         Dim tPost As PostClass = GetCurTabPost(Index)
1529
1530         'If Not tPost.IsRead AndAlso SettingDialog.UnreadManage AndAlso _statuses.Tabs(_curTab.Text).UnreadManage Then
1531         '    Item.Font = _fntUnread
1532         'Else
1533         '    Item.Font = _fntReaded
1534         'End If
1535
1536         If _post Is Nothing Then Exit Sub
1537
1538         If Item.Index = -1 Then
1539             Item.BackColor = JudgeColor(_post, tPost)
1540         Else
1541             _curList.ChangeItemBackColor(Item.Index, JudgeColor(_post, tPost))
1542         End If
1543     End Sub
1544
1545     Private Function JudgeColor(ByVal BasePost As PostClass, ByVal TargetPost As PostClass) As Color
1546         Dim cl As Color
1547         If TargetPost.Id = BasePost.InReplyToId Then
1548             '@先
1549             cl = _clAtTo
1550         ElseIf TargetPost.IsMe Then
1551             '自分=発言者
1552             cl = _clSelf
1553         ElseIf TargetPost.Name.Equals(BasePost.Name, StringComparison.OrdinalIgnoreCase) Then
1554             '発言者
1555             cl = _clTarget
1556         ElseIf TargetPost.IsReply Then
1557             '自分宛返信
1558             cl = _clAtSelf
1559         ElseIf BasePost.ReplyToList.Contains(TargetPost.Name.ToLower()) Then
1560             '返信先
1561             cl = _clAtFromTarget
1562         ElseIf TargetPost.ReplyToList.Contains(BasePost.Name.ToLower()) Then
1563             'その人への返信
1564             cl = _clAtTarget
1565         Else
1566             'その他
1567             'cl = System.Drawing.SystemColors.Window
1568             cl = _clListBackcolor
1569         End If
1570         Return cl
1571     End Function
1572
1573     Private Sub PostButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PostButton.Click
1574         If StatusText.Text.Trim.Length = 0 Then
1575             DoRefresh()
1576             Exit Sub
1577         End If
1578
1579         _history(_history.Count - 1) = StatusText.Text.Trim
1580
1581         If SettingDialog.UrlConvertAuto Then UrlConvertAutoToolStripMenuItem_Click(Nothing, Nothing)
1582         Dim args As New GetWorkerArg()
1583         args.page = 0
1584         args.endPage = 0
1585         args.type = WORKERTYPE.PostMessage
1586         CheckReplyTo(StatusText.Text)
1587
1588         '整形によって増加する文字数を取得
1589         Dim adjustCount As Integer = 0
1590         Dim tmpStatus As String = StatusText.Text.Trim
1591         If ToolStripMenuItemApiCommandEvasion.Checked Then
1592             ' APIコマンド回避
1593             Dim regex As New Regex("^[+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]*(get|g|fav|follow|f|on|off|stop|quit|leave|l|whois|w|nudge|n|stats|invite|track|untrack|tracks|tracking|\*)([+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]+|$)", RegexOptions.IgnoreCase)
1594             If regex.IsMatch(tmpStatus) AndAlso tmpStatus.EndsWith(" .") = False Then adjustCount += 2
1595         End If
1596
1597         If ToolStripMenuItemUrlMultibyteSplit.Checked Then
1598             ' URLと全角文字の切り離し
1599             Dim regex2 As New Regex("https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+")
1600             adjustCount += regex2.Matches(tmpStatus).Count
1601         End If
1602
1603         If IdeographicSpaceToSpaceToolStripMenuItem.Checked Then
1604             ' 文中の全角スペースを半角スペース2個にする
1605             For i As Integer = 0 To tmpStatus.Length - 1
1606                 If tmpStatus.Substring(i, 1) = " " Then adjustCount += 1
1607             Next
1608         End If
1609
1610
1611         Dim isCutOff As Boolean = False
1612         Dim isRemoveFooter As Boolean = My.Computer.Keyboard.ShiftKeyDown
1613         If StatusText.Multiline AndAlso Not SettingDialog.PostCtrlEnter Then
1614             '複数行でEnter投稿の場合、Ctrlも押されていたらフッタ付加しない
1615             isRemoveFooter = My.Computer.Keyboard.CtrlKeyDown
1616         End If
1617         If Not isRemoveFooter AndAlso (StatusText.Text.Contains("RT @") OrElse StatusText.Text.Contains("QT @")) Then
1618             isRemoveFooter = True
1619         End If
1620         If GetRestStatusCount(False, Not isRemoveFooter) - adjustCount < 0 Then
1621             If MessageBox.Show(My.Resources.PostLengthOverMessage1, My.Resources.PostLengthOverMessage2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.OK Then
1622                 isCutOff = True
1623                 If Not SettingDialog.UrlConvertAuto Then UrlConvertAutoToolStripMenuItem_Click(Nothing, Nothing)
1624                 If GetRestStatusCount(False, Not isRemoveFooter) - adjustCount < 0 Then
1625                     isRemoveFooter = True
1626                 End If
1627             Else
1628                 Exit Sub
1629             End If
1630         End If
1631
1632         If (StatusText.Text.StartsWith("D ")) OrElse isRemoveFooter Then
1633             args.status = StatusText.Text.Trim
1634         ElseIf SettingDialog.UseRecommendStatus() Then
1635             ' 推奨ステータスを使用する
1636             args.status = StatusText.Text.Trim() + SettingDialog.RecommendStatusText
1637         Else
1638             ' テキストボックスに入力されている文字列を使用する
1639             args.status = StatusText.Text.Trim() + " " + SettingDialog.Status.Trim()
1640         End If
1641
1642         If ToolStripMenuItemApiCommandEvasion.Checked Then
1643             ' APIコマンド回避
1644             Dim regex As New Regex("^[+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]*(get|g|fav|follow|f|on|off|stop|quit|leave|l|whois|w|nudge|n|stats|invite|track|untrack|tracks|tracking|\*)([+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]+|$)", RegexOptions.IgnoreCase)
1645             If regex.IsMatch(args.status) AndAlso args.status.EndsWith(" .") = False Then args.status += " ."
1646         End If
1647
1648         If ToolStripMenuItemUrlMultibyteSplit.Checked Then
1649             ' URLと全角文字の切り離し
1650             Dim regex2 As New Regex("https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+")
1651             Dim mc2 As Match = regex2.Match(args.status)
1652             If mc2.Success Then args.status = regex2.Replace(args.status, "$& ")
1653         End If
1654
1655         If IdeographicSpaceToSpaceToolStripMenuItem.Checked Then
1656             ' 文中の全角スペースを半角スペース2個にする
1657             args.status = args.status.Replace(" ", "  ")
1658         End If
1659
1660         If isCutOff AndAlso args.status.Length > 140 Then args.status = args.status.Substring(0, 140)
1661
1662         RunAsync(args)
1663
1664         DirectCast(ListTab.SelectedTab.Tag, Control).Focus()
1665     End Sub
1666
1667     Private Sub EndToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles EndToolStripMenuItem.Click
1668         _endingFlag = True
1669         Me.Close()
1670     End Sub
1671
1672     Private Sub Tween_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
1673         If Not SettingDialog.CloseToExit AndAlso e.CloseReason = CloseReason.UserClosing AndAlso _endingFlag = False Then
1674             '_endingFlag=False:フォームの×ボタン
1675             e.Cancel = True
1676             Me.Visible = False
1677         Else
1678             _ignoreConfigSave = True
1679             _endingFlag = True
1680             TimerTimeline.Enabled = False
1681             TimerReply.Enabled = False
1682             TimerDM.Enabled = False
1683             TimerColorize.Enabled = False
1684             TimerRefreshIcon.Enabled = False
1685         End If
1686     End Sub
1687
1688     Private Sub NotifyIcon1_BalloonTipClicked(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NotifyIcon1.BalloonTipClicked
1689         Me.Visible = True
1690         If Me.WindowState = FormWindowState.Minimized Then
1691             Me.WindowState = FormWindowState.Normal
1692         End If
1693         Me.Activate()
1694     End Sub
1695
1696     Private Sub GetTimelineWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
1697         Dim bw As BackgroundWorker = DirectCast(sender, BackgroundWorker)
1698         If bw.CancellationPending OrElse _endingFlag Then
1699             e.Cancel = True
1700             Exit Sub
1701         End If
1702
1703         Threading.Thread.CurrentThread.Priority = Threading.ThreadPriority.BelowNormal
1704
1705         My.Application.InitCulture()
1706
1707         Dim ret As String = ""
1708         Dim rslt As New GetWorkerResult()
1709
1710         Dim read As Boolean = Not SettingDialog.UnreadManage
1711         If _initial AndAlso SettingDialog.UnreadManage Then read = SettingDialog.Readed
1712
1713         Dim args As GetWorkerArg = DirectCast(e.Argument, GetWorkerArg)
1714
1715
1716         If args.type <> WORKERTYPE.OpenUri Then bw.ReportProgress(0, "") 'Notifyアイコンアニメーション開始
1717         Select Case args.type
1718             Case WORKERTYPE.Timeline, WORKERTYPE.Reply
1719                 bw.ReportProgress(50, MakeStatusMessage(args, False))
1720                 If SettingDialog.UseAPI Then
1721                     ret = Twitter.GetTimelineApi(read, args.type)
1722                 Else
1723                     ret = Twitter.GetTimeline(args.page, read, args.endPage, args.type, rslt.newDM)
1724                 End If
1725                 '新着時未読クリア
1726                 If ret = "" AndAlso args.type = WORKERTYPE.Timeline AndAlso SettingDialog.ReadOldPosts Then
1727                     _statuses.SetRead()
1728                 End If
1729                 rslt.addCount = _statuses.DistributePosts()
1730             Case WORKERTYPE.DirectMessegeRcv    '送信分もまとめて取得
1731                 bw.ReportProgress(50, MakeStatusMessage(args, False))
1732                 If SettingDialog.UseAPI Then
1733                     ret = Twitter.GetDirectMessageApi(read, WORKERTYPE.DirectMessegeRcv)
1734                     If ret = "" Then ret = Twitter.GetDirectMessageApi(read, WORKERTYPE.DirectMessegeSnt)
1735                 Else
1736                     ret = Twitter.GetDirectMessage(args.page, read, args.endPage, args.type)
1737                 End If
1738                 rslt.addCount = _statuses.DistributePosts()
1739             Case WORKERTYPE.FavAdd
1740                 'スレッド処理はしない
1741                 For i As Integer = 0 To args.ids.Count - 1
1742                     Dim post As PostClass = _statuses.Item(args.ids(i))
1743                     args.page = i + 1
1744                     bw.ReportProgress(50, MakeStatusMessage(args, False))
1745                     If Not post.IsFav Then
1746                         If post.RetweetedId = 0 Then
1747                             ret = Twitter.PostFavAdd(post.Id)
1748                         Else
1749                             ret = Twitter.PostFavAdd(post.RetweetedId)
1750                         End If
1751                         If ret.Length = 0 Then
1752                             args.sIds.Add(post.Id)
1753                             post.IsFav = True    'リスト再描画必要
1754                             _favTimestamps.Add(Now)
1755                             _statuses.GetTabByType(TabUsageType.Favorites).Add(post.Id, post.IsRead, False)
1756                         End If
1757                     End If
1758                 Next
1759                 rslt.sIds = args.sIds
1760             Case WORKERTYPE.FavRemove
1761                 'スレッド処理はしない
1762                 For i As Integer = 0 To args.ids.Count - 1
1763                     Dim post As PostClass = _statuses.Item(args.ids(i))
1764                     args.page = i + 1
1765                     bw.ReportProgress(50, MakeStatusMessage(args, False))
1766                     If post.IsFav Then
1767                         If post.RetweetedId = 0 Then
1768                             ret = Twitter.PostFavRemove(post.Id)
1769                         Else
1770                             ret = Twitter.PostFavRemove(post.RetweetedId)
1771                         End If
1772                         If ret.Length = 0 Then
1773                             args.sIds.Add(post.Id)
1774                             post.IsFav = False    'リスト再描画必要
1775                         End If
1776                     End If
1777                 Next
1778                 rslt.sIds = args.sIds
1779                 ' Contributed by shuyoko <http://twitter.com/shuyoko> BEGIN:
1780             Case WORKERTYPE.BlackFavAdd
1781                 'スレッド処理はしない
1782                 For i As Integer = 0 To args.ids.Count - 1
1783                     Dim post As PostClass = _statuses.Item(args.ids(i))
1784                     Dim blackid As Long = 0
1785                     args.page = i + 1
1786                     bw.ReportProgress(50, MakeStatusMessage(args, False))
1787                     If Not post.IsFav Then
1788                         ret = Twitter.GetBlackFavId(post.Id, blackid)
1789                         If ret.Length = 0 Then
1790                             ret = Twitter.PostFavAdd(blackid)
1791                             If ret.Length = 0 Then
1792                                 args.sIds.Add(post.Id)
1793                                 post.IsFav = True    'リスト再描画必要
1794                                 _favTimestamps.Add(Now)
1795                             End If
1796                         End If
1797                     End If
1798                 Next
1799                 rslt.sIds = args.sIds
1800                 ' Contributed by shuyoko <http://twitter.com/shuyoko> END.
1801             Case WORKERTYPE.PostMessage
1802                 bw.ReportProgress(200)
1803                 For i As Integer = 0 To 1
1804                     ret = Twitter.PostStatus(args.status, _reply_to_id)
1805                     If ret = "" OrElse ret = "OK:Delaying?" OrElse ret.StartsWith("Outputz:") Then Exit For
1806                 Next
1807                 If ret = "" OrElse ret.StartsWith("Outputz") OrElse ret.StartsWith("OK:") Then
1808                     _reply_to_id = 0
1809                     _reply_to_name = ""
1810                 End If
1811                 bw.ReportProgress(300)
1812             Case WORKERTYPE.Retweet
1813                 bw.ReportProgress(200)
1814                 ret = Twitter.PostRetweet(args.ids(0))
1815                 bw.ReportProgress(300)
1816             Case WORKERTYPE.Follower
1817                 bw.ReportProgress(50, My.Resources.UpdateFollowersMenuItem1_ClickText1)
1818                 If SettingDialog.UseAPI Then
1819                     ret = Twitter.GetFollowersApi()
1820                 Else
1821                     ret = Twitter.GetFollowers(False)       ' Followersリストキャッシュ有効
1822                 End If
1823                 Twitter.RefreshOwl()    '洗い換え
1824             Case WORKERTYPE.OpenUri
1825                 Dim myPath As String = Convert.ToString(args.status)
1826
1827                 Try
1828                     If SettingDialog.BrowserPath <> "" Then
1829                         'Shell(SettingDialog.BrowserPath & " " & myPath)
1830                         If SettingDialog.BrowserPath.StartsWith("""") AndAlso SettingDialog.BrowserPath.Length > 2 AndAlso SettingDialog.BrowserPath.IndexOf("""", 2) > -1 Then
1831                             Dim sep As Integer = SettingDialog.BrowserPath.IndexOf("""", 2)
1832                             Dim browserPath As String = SettingDialog.BrowserPath.Substring(1, sep - 1)
1833                             Dim arg As String = ""
1834                             If sep < SettingDialog.BrowserPath.Length - 1 Then
1835                                 arg = SettingDialog.BrowserPath.Substring(sep + 1)
1836                             End If
1837                             myPath = arg + " " + myPath
1838                             System.Diagnostics.Process.Start(browserPath, myPath)
1839                         Else
1840                             System.Diagnostics.Process.Start(SettingDialog.BrowserPath, myPath)
1841                         End If
1842                     Else
1843                         System.Diagnostics.Process.Start(myPath)
1844                     End If
1845                 Catch ex As Exception
1846                     '                MessageBox.Show("ブラウザの起動に失敗、またはタイムアウトしました。" + ex.ToString())
1847                 End Try
1848             Case WORKERTYPE.Favorites
1849                 bw.ReportProgress(50, MakeStatusMessage(args, False))
1850                 If SettingDialog.UseAPI Then
1851                     ret = Twitter.GetFavoritesApi(read, args.type)
1852                 Else
1853                     ret = Twitter.GetFavorites(args.page, read, args.endPage, args.type, rslt.newDM)
1854                 End If
1855                 rslt.addCount = _statuses.DistributePosts()
1856         End Select
1857         'キャンセル要求
1858         If bw.CancellationPending Then
1859             e.Cancel = True
1860             Exit Sub
1861         End If
1862
1863         '時速表示用
1864         If args.type = WORKERTYPE.FavAdd OrElse args.type = WORKERTYPE.BlackFavAdd Then
1865             Dim oneHour As Date = Now.Subtract(New TimeSpan(1, 0, 0))
1866             For i As Integer = _favTimestamps.Count - 1 To 0 Step -1
1867                 If _favTimestamps(i).CompareTo(oneHour) < 0 Then
1868                     _favTimestamps.RemoveAt(i)
1869                 End If
1870             Next
1871         End If
1872         If args.type = WORKERTYPE.Timeline AndAlso Not _initial Then
1873             SyncLock _syncObject
1874                 Dim tm As Date = Now
1875                 If _tlTimestamps.ContainsKey(tm) Then
1876                     _tlTimestamps(tm) += rslt.addCount
1877                 Else
1878                     _tlTimestamps.Add(Now, rslt.addCount)
1879                 End If
1880                 Dim oneHour As Date = Now.Subtract(New TimeSpan(1, 0, 0))
1881                 Dim keys As New List(Of Date)
1882                 _tlCount = 0
1883                 For Each key As Date In _tlTimestamps.Keys
1884                     If key.CompareTo(oneHour) < 0 Then
1885                         keys.Add(key)
1886                     Else
1887                         _tlCount += _tlTimestamps(key)
1888                     End If
1889                 Next
1890                 For Each key As Date In keys
1891                     _tlTimestamps.Remove(key)
1892                 Next
1893                 keys.Clear()
1894             End SyncLock
1895         End If
1896
1897         '終了ステータス
1898         If args.type <> WORKERTYPE.OpenUri Then bw.ReportProgress(100, MakeStatusMessage(args, True)) 'ステータス書き換え、Notifyアイコンアニメーション開始
1899
1900         rslt.retMsg = ret
1901         rslt.type = args.type
1902         rslt.tName = args.tName
1903         If args.type = WORKERTYPE.DirectMessegeRcv OrElse _
1904            args.type = WORKERTYPE.DirectMessegeSnt OrElse _
1905            args.type = WORKERTYPE.Reply OrElse _
1906            args.type = WORKERTYPE.Timeline OrElse _
1907            args.type = WORKERTYPE.Favorites Then
1908             rslt.page = args.page - 1   '値が正しいか後でチェック。10ページ毎の継続確認
1909         End If
1910
1911         e.Result = rslt
1912
1913     End Sub
1914
1915     Private Function MakeStatusMessage(ByVal AsyncArg As GetWorkerArg, ByVal Finish As Boolean) As String
1916         Dim smsg As String = ""
1917         If Not Finish Then
1918             '継続中メッセージ
1919             Select Case AsyncArg.type
1920                 Case WORKERTYPE.Timeline
1921                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText5 + AsyncArg.page.ToString() + My.Resources.GetTimelineWorker_RunWorkerCompletedText6
1922                 Case WORKERTYPE.Reply
1923                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText4 + AsyncArg.page.ToString() + My.Resources.GetTimelineWorker_RunWorkerCompletedText6
1924                 Case WORKERTYPE.DirectMessegeRcv
1925                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText8 + AsyncArg.page.ToString() + My.Resources.GetTimelineWorker_RunWorkerCompletedText6
1926                     'Case WORKERTYPE.DirectMessegeSnt
1927                     '    smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText12 + AsyncArg.page.ToString() + My.Resources.GetTimelineWorker_RunWorkerCompletedText6
1928                 Case WORKERTYPE.FavAdd
1929                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText15 + AsyncArg.page.ToString() + "/" + AsyncArg.ids.Count.ToString() + _
1930                                         My.Resources.GetTimelineWorker_RunWorkerCompletedText16 + (AsyncArg.page - AsyncArg.sIds.Count - 1).ToString()
1931                 Case WORKERTYPE.FavRemove
1932                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText17 + AsyncArg.page.ToString() + "/" + AsyncArg.ids.Count.ToString() + _
1933                                         My.Resources.GetTimelineWorker_RunWorkerCompletedText18 + (AsyncArg.page - AsyncArg.sIds.Count - 1).ToString()
1934                 Case WORKERTYPE.BlackFavAdd
1935                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText15_black + AsyncArg.page.ToString() + "/" + AsyncArg.ids.Count.ToString() + _
1936                                         My.Resources.GetTimelineWorker_RunWorkerCompletedText16 + (AsyncArg.page - AsyncArg.sIds.Count - 1).ToString()
1937                 Case WORKERTYPE.Favorites
1938                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText19
1939             End Select
1940         Else
1941             '完了メッセージ
1942             Select Case AsyncArg.type
1943                 Case WORKERTYPE.Timeline
1944                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText1
1945                 Case WORKERTYPE.Reply
1946                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText9
1947                 Case WORKERTYPE.DirectMessegeRcv
1948                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText11
1949                 Case WORKERTYPE.DirectMessegeSnt
1950                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText13
1951                 Case WORKERTYPE.FavAdd
1952                     '進捗メッセージ残す
1953                 Case WORKERTYPE.FavRemove
1954                     '進捗メッセージ残す
1955                 Case WORKERTYPE.BlackFavAdd
1956                     '進捗メッセージ残す
1957                 Case WORKERTYPE.Favorites
1958                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText20
1959                 Case WORKERTYPE.Follower
1960                     smsg = My.Resources.UpdateFollowersMenuItem1_ClickText3
1961             End Select
1962         End If
1963         Return smsg
1964     End Function
1965
1966     Private Sub GetTimelineWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs)
1967         If _endingFlag Then Exit Sub
1968         If e.ProgressPercentage > 100 Then
1969             '発言投稿
1970             If e.ProgressPercentage = 200 Then    '開始
1971                 StatusLabel.Text = "Posting..."
1972                 StatusText.Enabled = False
1973                 PostButton.Enabled = False
1974                 ReplyStripMenuItem.Enabled = False
1975                 DMStripMenuItem.Enabled = False
1976             End If
1977             If e.ProgressPercentage = 300 Then  '終了
1978                 StatusLabel.Text = My.Resources.PostWorker_RunWorkerCompletedText4
1979                 StatusText.Enabled = True
1980                 PostButton.Enabled = True
1981                 ReplyStripMenuItem.Enabled = True
1982                 DMStripMenuItem.Enabled = True
1983             End If
1984         Else
1985             Dim smsg As String = DirectCast(e.UserState, String)
1986             If smsg.Length > 0 Then StatusLabel.Text = smsg
1987         End If
1988     End Sub
1989
1990     Private Sub GetTimelineWorker_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
1991
1992         If _endingFlag OrElse e.Cancelled Then Exit Sub 'キャンセル
1993
1994         IsNetworkAvailable()
1995
1996         'If _myStatusOnline Then
1997         '    'タイマー再始動
1998         '    If SettingDialog.TimelinePeriodInt > 0 AndAlso Not TimerTimeline.Enabled Then TimerTimeline.Enabled = True
1999         '    If SettingDialog.DMPeriodInt > 0 AndAlso Not TimerDM.Enabled Then TimerDM.Enabled = True
2000         '    If SettingDialog.ReplyPeriodInt > 0 AndAlso Not TimerReply.Enabled Then TimerReply.Enabled = True
2001         'End If
2002
2003         If e.Error IsNot Nothing Then
2004             _myStatusError = True
2005             _waitTimeline = False
2006             _waitReply = False
2007             _waitDm = False
2008             _waitFav = False
2009             Throw New Exception("BackgroundWorker Exception", e.Error)
2010             Exit Sub
2011         End If
2012
2013         Dim rslt As GetWorkerResult = DirectCast(e.Result, GetWorkerResult)
2014         Dim args As New GetWorkerArg()
2015
2016         If rslt.type = WORKERTYPE.OpenUri Then Exit Sub
2017
2018         'エラー
2019         If rslt.retMsg.Length > 0 Then
2020             _myStatusError = True
2021             StatusLabel.Text = rslt.retMsg
2022             'If Twitter.AccountState = ACCOUNT_STATE.Invalid Then
2023             '    Try
2024             '        Twitter.AccountState = ACCOUNT_STATE.Validating
2025             '        SettingStripMenuItem_Click(Nothing, Nothing)
2026             '        Twitter.AccountState = ACCOUNT_STATE.Valid
2027             '    Catch ex As Exception
2028             '        Twitter.AccountState = ACCOUNT_STATE.Invalid
2029             '    End Try
2030             'End If
2031         End If
2032
2033         If rslt.type = WORKERTYPE.FavRemove Then
2034             DispSelectedPost()          ' 詳細画面書き直し
2035             Dim favTabName As String = _statuses.GetTabByType(TabUsageType.Favorites).TabName
2036             For Each i As Long In rslt.sIds
2037                 _statuses.RemovePost(favTabName, i)
2038             Next
2039             If _curTab.Text.Equals(favTabName) Then
2040                 _itemCache = Nothing    'キャッシュ破棄
2041                 _postCache = Nothing
2042                 _curPost = Nothing
2043                 _curItemIndex = -1
2044             End If
2045             For Each tp As TabPage In ListTab.TabPages
2046                 If tp.Text = favTabName Then
2047                     DirectCast(tp.Tag, DetailsListView).VirtualListSize = _statuses.Tabs(favTabName).AllCount
2048                     Exit For
2049                 End If
2050             Next
2051         End If
2052
2053         'リストに反映
2054         Dim busy As Boolean = False
2055         For Each bw As BackgroundWorker In _bw
2056             If bw IsNot Nothing AndAlso bw.IsBusy Then
2057                 busy = True
2058                 Exit For
2059             End If
2060         Next
2061         If Not busy Then RefreshTimeline() 'background処理なければ、リスト反映
2062
2063         Select Case rslt.type
2064             Case WORKERTYPE.Timeline
2065                 _waitTimeline = False
2066                 If Not _initial Then
2067                     '通常時
2068                     '自動調整
2069                     If Not SettingDialog.UseAPI Then
2070                         If SettingDialog.PeriodAdjust AndAlso SettingDialog.TimelinePeriodInt > 0 Then
2071                             If rslt.addCount >= 20 Then
2072                                 Dim itv As Integer = TimerTimeline.Interval
2073                                 itv -= 5000
2074                                 If itv < 15000 Then itv = 15000
2075                                 TimerTimeline.Interval = itv
2076                             Else
2077                                 TimerTimeline.Interval += 1000
2078                                 If TimerTimeline.Interval > SettingDialog.TimelinePeriodInt * 1000 Then TimerTimeline.Interval = SettingDialog.TimelinePeriodInt * 1000
2079                             End If
2080                         End If
2081                         If rslt.newDM Then
2082                             GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0)
2083                         End If
2084                     Else
2085                         'API使用時の取得調整は別途考える(カウント調整?)
2086                     End If
2087                 End If
2088             Case WORKERTYPE.Reply
2089                 _waitReply = False
2090                 If rslt.newDM AndAlso Not _initial Then
2091                     GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0)
2092                 End If
2093             Case WORKERTYPE.Favorites
2094                 _waitFav = False
2095             Case WORKERTYPE.DirectMessegeRcv
2096                 _waitDm = False
2097             Case WORKERTYPE.FavAdd, WORKERTYPE.BlackFavAdd, WORKERTYPE.FavRemove
2098                 _curList.BeginUpdate()
2099                 If rslt.type = WORKERTYPE.FavRemove AndAlso _statuses.Tabs(_curTab.Text).TabType = TabUsageType.Favorites Then
2100                     '色変えは不要
2101                 Else
2102                     For i As Integer = 0 To rslt.sIds.Count - 1
2103                         If _curTab.Text.Equals(rslt.tName) Then
2104                             Dim idx As Integer = _statuses.Tabs(rslt.tName).IndexOf(rslt.sIds(i))
2105                             If idx > -1 Then
2106                                 Dim post As PostClass = _statuses.Item(rslt.sIds(i))
2107                                 ChangeCacheStyleRead(post.IsRead, idx, _curTab)
2108                                 If idx = _curItemIndex Then DispSelectedPost() '選択アイテム再表示
2109                             End If
2110                         End If
2111                     Next
2112                 End If
2113                 _curList.EndUpdate()
2114             Case WORKERTYPE.PostMessage
2115                 urlUndoBuffer = Nothing
2116                 UrlUndoToolStripMenuItem.Enabled = False  'Undoをできないように設定
2117
2118                 If rslt.retMsg.Length > 0 AndAlso Not rslt.retMsg.StartsWith("Outputz") AndAlso rslt.retMsg <> "OK:Delaying?" Then
2119                     StatusLabel.Text = rslt.retMsg
2120                 Else
2121                     _postTimestamps.Add(Now)
2122                     Dim oneHour As Date = Now.Subtract(New TimeSpan(1, 0, 0))
2123                     For i As Integer = _postTimestamps.Count - 1 To 0 Step -1
2124                         If _postTimestamps(i).CompareTo(oneHour) < 0 Then
2125                             _postTimestamps.RemoveAt(i)
2126                         End If
2127                     Next
2128
2129                     If rslt.retMsg.Length > 0 Then StatusLabel.Text = rslt.retMsg 'Outputz失敗時
2130
2131                     If rslt.retMsg = "OK:Delaying?" Then
2132                         MessageBox.Show(rslt.retMsg, "Delay or DuplicationLimit", MessageBoxButtons.OK, MessageBoxIcon.Information)
2133                     End If
2134
2135                     StatusText.Text = ""
2136                     _history.Add("")
2137                     _hisIdx = _history.Count - 1
2138                     SetMainWindowTitle()
2139                 End If
2140                 If rslt.retMsg.Length = 0 AndAlso SettingDialog.PostAndGet Then GetTimeline(WORKERTYPE.Timeline, 1, 0)
2141             Case WORKERTYPE.Retweet
2142                 If rslt.retMsg.Length > 0 Then
2143                     StatusLabel.Text = rslt.retMsg
2144                 Else
2145                     _postTimestamps.Add(Now)
2146                     Dim oneHour As Date = Now.Subtract(New TimeSpan(1, 0, 0))
2147                     For i As Integer = _postTimestamps.Count - 1 To 0 Step -1
2148                         If _postTimestamps(i).CompareTo(oneHour) < 0 Then
2149                             _postTimestamps.RemoveAt(i)
2150                         End If
2151                     Next
2152                 End If
2153                 If rslt.retMsg.Length = 0 AndAlso SettingDialog.PostAndGet Then GetTimeline(WORKERTYPE.Timeline, 1, 0)
2154             Case WORKERTYPE.Follower
2155                 '_waitFollower = False
2156                 _itemCache = Nothing
2157                 _postCache = Nothing
2158                 _curList.Refresh()
2159         End Select
2160
2161     End Sub
2162
2163     Private Sub GetTimeline(ByVal WkType As WORKERTYPE, ByVal fromPage As Integer, ByVal toPage As Integer)
2164         'toPage=0:通常モード
2165         If Not IsNetworkAvailable() Then Exit Sub
2166         'タイマー停止
2167         If SettingDialog.UseAPI Then
2168             Select Case WkType
2169                 Case WORKERTYPE.Timeline
2170                     'TimerTimeline.Enabled = False
2171                 Case WORKERTYPE.Reply
2172                     'TimerReply.Enabled = False
2173                 Case WORKERTYPE.DirectMessegeRcv, WORKERTYPE.DirectMessegeSnt
2174                     'TimerDM.Enabled = False
2175             End Select
2176         Else
2177             Select Case WkType
2178                 Case WORKERTYPE.Timeline
2179                     'TimerTimeline.Enabled = False
2180                 Case WORKERTYPE.Reply
2181                     'TimerReply.Enabled = False
2182                 Case WORKERTYPE.DirectMessegeRcv, WORKERTYPE.DirectMessegeSnt
2183                     'TimerDM.Enabled = False
2184             End Select
2185         End If
2186         '非同期実行引数設定
2187         Dim args As New GetWorkerArg
2188         args.page = fromPage
2189         args.endPage = toPage
2190         args.type = WkType
2191
2192         RunAsync(args)
2193
2194         'Timeline取得モードの場合はReplyも同時に取得
2195         If Not SettingDialog.UseAPI AndAlso _
2196            Not _initial AndAlso _
2197            WkType = WORKERTYPE.Timeline AndAlso _
2198            SettingDialog.CheckReply Then
2199             TimerReply.Enabled = False
2200             Dim _args As New GetWorkerArg
2201             _args.page = fromPage
2202             _args.endPage = toPage
2203             _args.type = WORKERTYPE.Reply
2204             RunAsync(_args)
2205         End If
2206     End Sub
2207
2208     Private Function NextPageMessage(ByVal page As Integer) As DialogResult
2209         Dim flashRslt As Integer = Win32Api.FlashWindow(Me.Handle.ToInt32, 1)
2210         Return MessageBox.Show((page * 20).ToString + My.Resources.GetTimelineWorker_RunWorkerCompletedText2, _
2211                            My.Resources.GetTimelineWorker_RunWorkerCompletedText3, _
2212                            MessageBoxButtons.YesNo, _
2213                            MessageBoxIcon.Question)
2214     End Function
2215
2216     Private Sub NotifyIcon1_MouseClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.MouseClick
2217         If e.Button = Windows.Forms.MouseButtons.Left Then
2218             Me.Visible = True
2219             If Me.WindowState = FormWindowState.Minimized Then
2220                 Me.WindowState = FormWindowState.Normal
2221             End If
2222             Me.Activate()
2223         End If
2224     End Sub
2225
2226     Private Sub MyList_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
2227         MakeReplyOrDirectStatus()
2228     End Sub
2229
2230     Private Sub FavAddToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FavAddToolStripMenuItem.Click
2231         If _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage OrElse _curList.SelectedIndices.Count = 0 Then Exit Sub
2232
2233         '複数fav確認msg
2234         If _curList.SelectedIndices.Count > 1 Then
2235             If MessageBox.Show(My.Resources.FavAddToolStripMenuItem_ClickText1, My.Resources.FavAddToolStripMenuItem_ClickText2, _
2236                                MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
2237                 Exit Sub
2238             End If
2239         End If
2240
2241         Dim args As New GetWorkerArg
2242         args.ids = New List(Of Long)
2243         args.sIds = New List(Of Long)
2244         args.tName = _curTab.Text
2245         args.type = WORKERTYPE.FavAdd
2246         For Each idx As Integer In _curList.SelectedIndices
2247             Dim post As PostClass = GetCurTabPost(idx)
2248             If Not post.IsFav Then args.ids.Add(post.Id)
2249         Next
2250         If args.ids.Count = 0 Then
2251             StatusLabel.Text = My.Resources.FavAddToolStripMenuItem_ClickText4
2252             Exit Sub
2253         End If
2254
2255         RunAsync(args)
2256     End Sub
2257
2258     Private Sub FavRemoveToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FavRemoveToolStripMenuItem.Click
2259         If _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage OrElse _curList.SelectedIndices.Count = 0 Then Exit Sub
2260
2261         If _curList.SelectedIndices.Count > 1 Then
2262             If MessageBox.Show(My.Resources.FavRemoveToolStripMenuItem_ClickText1, My.Resources.FavRemoveToolStripMenuItem_ClickText2, _
2263                                MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
2264                 Exit Sub
2265             End If
2266         End If
2267
2268         Dim args As New GetWorkerArg()
2269         args.ids = New List(Of Long)()
2270         args.sIds = New List(Of Long)()
2271         args.tName = _curTab.Text
2272         args.type = WORKERTYPE.FavRemove
2273         For Each idx As Integer In _curList.SelectedIndices
2274             Dim post As PostClass = GetCurTabPost(idx)
2275             If post.IsFav Then args.ids.Add(post.Id)
2276         Next
2277         If args.ids.Count = 0 Then
2278             StatusLabel.Text = My.Resources.FavRemoveToolStripMenuItem_ClickText4
2279             Exit Sub
2280         End If
2281
2282         RunAsync(args)
2283     End Sub
2284
2285     Private Function GetCurTabPost(ByVal Index As Integer) As PostClass
2286         If _postCache IsNot Nothing AndAlso Index >= _itemCacheIndex AndAlso Index < _itemCacheIndex + _postCache.Length Then
2287             Return _postCache(Index - _itemCacheIndex)
2288         Else
2289             Return _statuses.Item(_curTab.Text, Index)
2290         End If
2291     End Function
2292
2293
2294     Private Sub MoveToHomeToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MoveToHomeToolStripMenuItem.Click
2295         If _curList.SelectedIndices.Count > 0 Then
2296             OpenUriAsync("http://twitter.com/" + GetCurTabPost(_curList.SelectedIndices(0)).Name)
2297         End If
2298     End Sub
2299
2300     Private Sub MoveToFavToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MoveToFavToolStripMenuItem.Click
2301         If _curList.SelectedIndices.Count > 0 Then
2302             OpenUriAsync("http://twitter.com/" + GetCurTabPost(_curList.SelectedIndices(0)).Name + "/favorites")
2303         End If
2304     End Sub
2305
2306     Private Sub Tween_ClientSizeChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.ClientSizeChanged
2307         'ショートカットから最小化状態で起動した際の対応
2308         Static initialize As Boolean = False
2309
2310         If Me.WindowState <> FormWindowState.Minimized Then
2311             If initialize Then
2312                 If Me.WindowState = FormWindowState.Normal Then
2313                     _mySize = Me.ClientSize
2314                     _mySpDis = Me.SplitContainer1.SplitterDistance
2315                     If StatusText.Multiline Then _mySpDis2 = Me.StatusText.Height
2316                     modifySettingLocal = True
2317                 End If
2318             ElseIf _cfgLocal IsNot Nothing Then
2319                 '初回フォームレイアウト復元
2320                 Try
2321                     Me.SplitContainer1.SplitterDistance = _cfgLocal.SplitterDistance     'Splitterの位置設定
2322                     '発言欄複数行
2323                     StatusText.Multiline = _cfgLocal.StatusMultiline
2324                     If StatusText.Multiline Then
2325                         SplitContainer2.SplitterDistance = SplitContainer2.Height - _cfgLocal.StatusTextHeight - SplitContainer2.SplitterWidth
2326                     Else
2327                         SplitContainer2.SplitterDistance = SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth
2328                     End If
2329                     initialize = True
2330                 Catch ex As Exception
2331                 End Try
2332             End If
2333         End If
2334     End Sub
2335
2336     Private Sub MyList_ColumnClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs)
2337         If SettingDialog.SortOrderLock Then Exit Sub
2338         Dim mode As IdComparerClass.ComparerMode
2339         If _iconCol Then
2340             mode = IdComparerClass.ComparerMode.Id
2341         Else
2342             Select Case e.Column
2343                 Case 0, 5, 6    '0:アイコン,5:未読マーク,6:プロテクト・フィルターマーク
2344                     'ソートしない
2345                     Exit Sub
2346                 Case 1  'ニックネーム
2347                     mode = IdComparerClass.ComparerMode.Nickname
2348                 Case 2  '本文
2349                     mode = IdComparerClass.ComparerMode.Data
2350                 Case 3  '時刻=発言Id
2351                     mode = IdComparerClass.ComparerMode.Id
2352                 Case 4  '名前
2353                     mode = IdComparerClass.ComparerMode.Name
2354                 Case 7  'Source
2355                     mode = IdComparerClass.ComparerMode.Source
2356             End Select
2357         End If
2358         _statuses.ToggleSortOrder(mode)
2359         _itemCache = Nothing
2360         _postCache = Nothing
2361         _curList.Refresh()
2362         modifySettingCommon = True
2363     End Sub
2364
2365     Private Sub Tween_LocationChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LocationChanged
2366         If Me.WindowState = FormWindowState.Normal Then
2367             _myLoc = Me.DesktopLocation
2368             modifySettingLocal = True
2369         End If
2370     End Sub
2371
2372     Private Sub ContextMenuStrip2_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip2.Opening
2373         If ListTab.SelectedTab Is Nothing Then Exit Sub
2374         If _statuses Is Nothing OrElse _statuses.Tabs Is Nothing OrElse Not _statuses.Tabs.ContainsKey(ListTab.SelectedTab.Text) Then Exit Sub
2375         If _statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.DirectMessage Then
2376             FavAddToolStripMenuItem.Enabled = False
2377             FavRemoveToolStripMenuItem.Enabled = False
2378             StatusOpenMenuItem.Enabled = False
2379             FavorareMenuItem.Enabled = False
2380             BlackFavAddToolStripMenuItem.Enabled = False
2381             'BlackFavRemoveToolStripMenuItem.Enabled = False
2382         Else
2383             If IsNetworkAvailable() Then
2384                 FavAddToolStripMenuItem.Enabled = True
2385                 FavRemoveToolStripMenuItem.Enabled = True
2386                 StatusOpenMenuItem.Enabled = True
2387                 FavorareMenuItem.Enabled = True
2388                 BlackFavAddToolStripMenuItem.Enabled = True
2389                 'BlackFavRemoveToolStripMenuItem.Enabled = True
2390             End If
2391         End If
2392         If _curPost Is Nothing OrElse _curPost.IsDm Then
2393             ReTweetStripMenuItem.Enabled = False
2394             ReTweetOriginalStripMenuItem.Enabled = False
2395             QuoteStripMenuItem.Enabled = False
2396         Else
2397             ReTweetStripMenuItem.Enabled = True
2398             ReTweetOriginalStripMenuItem.Enabled = True
2399             QuoteStripMenuItem.Enabled = True
2400         End If
2401     End Sub
2402
2403     Private Sub ReplyStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReplyStripMenuItem.Click
2404         MakeReplyOrDirectStatus(False, True)
2405     End Sub
2406
2407     Private Sub DMStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DMStripMenuItem.Click
2408         MakeReplyOrDirectStatus(False, False)
2409     End Sub
2410
2411     Private Sub DeleteStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DeleteStripMenuItem.Click
2412         If _curTab Is Nothing OrElse _curList Is Nothing Then Exit Sub
2413         If _statuses.Tabs(_curTab.Text).TabType <> TabUsageType.DirectMessage Then
2414             Dim myPost As Boolean = False
2415             For Each idx As Integer In _curList.SelectedIndices
2416                 If GetCurTabPost(idx).IsMe Then
2417                     myPost = True
2418                     Exit For
2419                 End If
2420             Next
2421             If Not myPost Then Exit Sub
2422         End If
2423
2424         Dim tmp As String = String.Format(My.Resources.DeleteStripMenuItem_ClickText1, Environment.NewLine)
2425
2426         If MessageBox.Show(tmp, My.Resources.DeleteStripMenuItem_ClickText2, _
2427               MessageBoxButtons.OKCancel, _
2428               MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then Exit Sub
2429
2430         Dim fidx As Integer
2431         If _curList.FocusedItem IsNot Nothing Then
2432             fidx = _curList.FocusedItem.Index
2433         ElseIf _curList.TopItem IsNot Nothing Then
2434             fidx = _curList.TopItem.Index
2435         Else
2436             fidx = 0
2437         End If
2438
2439         Try
2440             Me.Cursor = Cursors.WaitCursor
2441
2442             Dim rslt As Boolean = True
2443             For Each Id As Long In _statuses.GetId(_curTab.Text, _curList.SelectedIndices)
2444                 Dim rtn As String = ""
2445                 If _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage Then
2446                     rtn = Twitter.RemoveDirectMessage(Id)
2447                 Else
2448                     If _statuses.Item(Id).IsMe Then
2449                         rtn = Twitter.RemoveStatus(Id)
2450                     Else
2451                         Continue For
2452                     End If
2453                 End If
2454                 If rtn.Length > 0 Then
2455                     'エラー
2456                     rslt = False
2457                 Else
2458                     _statuses.RemovePost(Id)
2459                 End If
2460             Next
2461
2462             If Not rslt Then
2463                 StatusLabel.Text = My.Resources.DeleteStripMenuItem_ClickText3  '失敗
2464             Else
2465                 StatusLabel.Text = My.Resources.DeleteStripMenuItem_ClickText4  '成功
2466             End If
2467
2468             _itemCache = Nothing    'キャッシュ破棄
2469             _postCache = Nothing
2470             _curPost = Nothing
2471             _curItemIndex = -1
2472             For Each tb As TabPage In ListTab.TabPages
2473                 DirectCast(tb.Tag, DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
2474                 If _curTab.Equals(tb) Then
2475                     _curList.SelectedIndices.Clear()
2476                     If _statuses.Tabs(tb.Text).AllCount > 0 Then
2477                         If _statuses.Tabs(tb.Text).AllCount - 1 > fidx AndAlso fidx > -1 Then
2478                             _curList.SelectedIndices.Add(fidx)
2479                         Else
2480                             _curList.SelectedIndices.Add(_statuses.Tabs(tb.Text).AllCount - 1)
2481                         End If
2482                         If _curList.SelectedIndices.Count > 0 Then
2483                             _curList.EnsureVisible(_curList.SelectedIndices(0))
2484                             _curList.FocusedItem = _curList.Items(_curList.SelectedIndices(0))
2485                         End If
2486                     End If
2487                 End If
2488                 If _statuses.Tabs(tb.Text).UnreadCount = 0 Then
2489                     If SettingDialog.TabIconDisp Then
2490                         If tb.ImageIndex = 0 Then tb.ImageIndex = -1 'タブアイコン
2491                     End If
2492                 End If
2493             Next
2494             If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
2495         Finally
2496             Me.Cursor = Cursors.Default
2497         End Try
2498     End Sub
2499
2500     Private Sub ReadedStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReadedStripMenuItem.Click
2501         _curList.BeginUpdate()
2502         If SettingDialog.UnreadManage Then
2503             For Each idx As Integer In _curList.SelectedIndices
2504                 _statuses.SetRead(True, _curTab.Text, idx)
2505             Next
2506         End If
2507         For Each idx As Integer In _curList.SelectedIndices
2508             ChangeCacheStyleRead(True, idx, _curTab)
2509         Next
2510         ColorizeList()
2511         _curList.EndUpdate()
2512         For Each tb As TabPage In ListTab.TabPages
2513             If _statuses.Tabs(tb.Text).UnreadCount = 0 Then
2514                 If SettingDialog.TabIconDisp Then
2515                     If tb.ImageIndex = 0 Then tb.ImageIndex = -1 'タブアイコン
2516                 End If
2517             End If
2518         Next
2519         If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
2520     End Sub
2521
2522     Private Sub UnreadStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UnreadStripMenuItem.Click
2523         _curList.BeginUpdate()
2524         If SettingDialog.UnreadManage Then
2525             For Each idx As Integer In _curList.SelectedIndices
2526                 _statuses.SetRead(False, _curTab.Text, idx)
2527             Next
2528         End If
2529         For Each idx As Integer In _curList.SelectedIndices
2530             ChangeCacheStyleRead(False, idx, _curTab)
2531         Next
2532         ColorizeList()
2533         _curList.EndUpdate()
2534         For Each tb As TabPage In ListTab.TabPages
2535             If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
2536                 If SettingDialog.TabIconDisp Then
2537                     If tb.ImageIndex = -1 Then tb.ImageIndex = 0 'タブアイコン
2538                 End If
2539             End If
2540         Next
2541         If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
2542     End Sub
2543
2544     Private Sub RefreshStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RefreshStripMenuItem.Click
2545         DoRefresh()
2546     End Sub
2547
2548     Private Sub DoRefresh()
2549         If _curTab IsNot Nothing Then
2550             Select Case _statuses.Tabs(_curTab.Text).TabType
2551                 Case TabUsageType.Mentions
2552                     GetTimeline(WORKERTYPE.Reply, 1, 0)
2553                 Case TabUsageType.DirectMessage
2554                     GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0)
2555                 Case TabUsageType.Favorites
2556                     GetTimeline(WORKERTYPE.Favorites, 1, 0)
2557                     'Case TabUsageType.Profile
2558                     '' TODO
2559                     'Case TabUsageType.PublicSearch
2560                     '' TODO
2561                 Case Else
2562                     GetTimeline(WORKERTYPE.Timeline, 1, 0)
2563             End Select
2564         Else
2565             GetTimeline(WORKERTYPE.Timeline, 1, 0)
2566         End If
2567     End Sub
2568
2569     Private Sub SettingStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SettingStripMenuItem.Click
2570         Dim chgUseApi As Boolean = False
2571         Dim result As DialogResult
2572
2573         Try
2574             result = SettingDialog.ShowDialog()
2575         Catch ex As Exception
2576             Exit Sub
2577         End Try
2578         If result = Windows.Forms.DialogResult.OK Then
2579             SyncLock _syncObject
2580                 _username = SettingDialog.UserID
2581                 _password = SettingDialog.PasswordStr
2582                 Twitter.Username = _username
2583                 Twitter.Password = _password
2584                 Try
2585                     If SettingDialog.TimelinePeriodInt > 0 Then
2586                         If SettingDialog.PeriodAdjust AndAlso Not SettingDialog.UseAPI Then
2587                             If SettingDialog.TimelinePeriodInt * 1000 < TimerTimeline.Interval Then
2588                                 TimerTimeline.Interval = SettingDialog.TimelinePeriodInt * 1000
2589                             End If
2590                         Else
2591                             TimerTimeline.Interval = SettingDialog.TimelinePeriodInt * 1000
2592                         End If
2593                         TimerTimeline.Enabled = True
2594                     Else
2595                         TimerTimeline.Interval = 600000
2596                         TimerTimeline.Enabled = False
2597                     End If
2598                     If SettingDialog.ReplyPeriodInt > 0 Then
2599                         TimerReply.Interval = SettingDialog.ReplyPeriodInt * 1000
2600                         TimerReply.Enabled = True
2601                     Else
2602                         TimerReply.Interval = 6000000
2603                         TimerReply.Enabled = False
2604                     End If
2605                     If SettingDialog.DMPeriodInt > 0 Then
2606                         TimerDM.Interval = SettingDialog.DMPeriodInt * 1000
2607                         TimerDM.Enabled = True
2608                     Else
2609                         TimerDM.Interval = 6000000
2610                         TimerDM.Enabled = False
2611                     End If
2612                 Catch ex As Exception
2613                     ex.Data("Instance") = "Set Timers"
2614                     ex.Data("IsTerminatePermission") = False
2615                     Throw
2616                 End Try
2617                 Twitter.NextThreshold = SettingDialog.NextPageThreshold
2618                 Twitter.NextPages = SettingDialog.NextPagesInt
2619                 If Twitter.UseAPI <> SettingDialog.UseAPI AndAlso Not _initial Then
2620                     chgUseApi = True
2621                 End If
2622                 Twitter.UseAPI = SettingDialog.UseAPI
2623                 Twitter.CountApi = SettingDialog.CountApi
2624                 Twitter.UsePostMethod = False
2625                 Twitter.HubServer = SettingDialog.HubServer
2626                 Twitter.TinyUrlResolve = SettingDialog.TinyUrlResolve
2627                 Twitter.RestrictFavCheck = SettingDialog.RestrictFavCheck
2628                 Twitter.ReadOwnPost = SettingDialog.ReadOwnPost
2629                 Twitter.UseSsl = SettingDialog.UseSsl
2630                 Twitter.BitlyId = SettingDialog.BitlyUser
2631                 Twitter.BitlyKey = SettingDialog.BitlyPwd
2632
2633                 Twitter.SelectedProxyType = SettingDialog.SelectedProxyType
2634                 Twitter.ProxyAddress = SettingDialog.ProxyAddress
2635                 Twitter.ProxyPort = SettingDialog.ProxyPort
2636                 Twitter.ProxyUser = SettingDialog.ProxyUser
2637                 Twitter.ProxyPassword = SettingDialog.ProxyPassword
2638                 Try
2639                     If SettingDialog.TabIconDisp Then
2640                         RemoveHandler ListTab.DrawItem, AddressOf ListTab_DrawItem
2641                         ListTab.DrawMode = TabDrawMode.Normal
2642                         ListTab.ImageList = Me.TabImage
2643                     Else
2644                         RemoveHandler ListTab.DrawItem, AddressOf ListTab_DrawItem
2645                         AddHandler ListTab.DrawItem, AddressOf ListTab_DrawItem
2646                         ListTab.DrawMode = TabDrawMode.OwnerDrawFixed
2647                         ListTab.ImageList = Nothing
2648                     End If
2649                 Catch ex As Exception
2650                     ex.Data("Instance") = "ListTab(TabIconDisp)"
2651                     ex.Data("IsTerminatePermission") = False
2652                     Throw
2653                 End Try
2654
2655                 Try
2656                     If Not SettingDialog.UnreadManage Then
2657                         ReadedStripMenuItem.Enabled = False
2658                         UnreadStripMenuItem.Enabled = False
2659                         If SettingDialog.TabIconDisp Then
2660                             For Each myTab As TabPage In ListTab.TabPages
2661                                 myTab.ImageIndex = -1
2662                             Next
2663                         End If
2664                     Else
2665                         ReadedStripMenuItem.Enabled = True
2666                         UnreadStripMenuItem.Enabled = True
2667                     End If
2668                 Catch ex As Exception
2669                     ex.Data("Instance") = "ListTab(UnreadManage)"
2670                     ex.Data("IsTerminatePermission") = False
2671                     Throw
2672                 End Try
2673
2674                 Try
2675                     For Each mytab As TabPage In ListTab.TabPages
2676                         Dim lst As DetailsListView = DirectCast(mytab.Tag, DetailsListView)
2677                         lst.GridLines = SettingDialog.ShowGrid
2678                     Next
2679                 Catch ex As Exception
2680                     ex.Data("Instance") = "ListTab(ShowGrid)"
2681                     ex.Data("IsTerminatePermission") = False
2682                     Throw
2683                 End Try
2684
2685                 PlaySoundMenuItem.Checked = SettingDialog.PlaySound
2686                 _fntUnread = SettingDialog.FontUnread
2687                 _clUnread = SettingDialog.ColorUnread
2688                 _fntReaded = SettingDialog.FontReaded
2689                 _clReaded = SettingDialog.ColorReaded
2690                 _clFav = SettingDialog.ColorFav
2691                 _clOWL = SettingDialog.ColorOWL
2692                 _clRetweet = SettingDialog.ColorRetweet
2693                 _fntDetail = SettingDialog.FontDetail
2694                 _clDetail = SettingDialog.ColorDetail
2695                 _clDetailLink = SettingDialog.ColorDetailLink
2696                 _clDetailBackcolor = SettingDialog.ColorDetailBackcolor
2697                 _clSelf = SettingDialog.ColorSelf
2698                 _clAtSelf = SettingDialog.ColorAtSelf
2699                 _clTarget = SettingDialog.ColorTarget
2700                 _clAtTarget = SettingDialog.ColorAtTarget
2701                 _clAtFromTarget = SettingDialog.ColorAtFromTarget
2702                 _clAtTo = SettingDialog.ColorAtTo
2703                 _clListBackcolor = SettingDialog.ColorListBackcolor
2704                 _clInputBackcolor = SettingDialog.ColorInputBackcolor
2705                 _clInputFont = SettingDialog.ColorInputFont
2706                 _fntInputFont = SettingDialog.FontInputFont
2707                 Try
2708                     If StatusText.Focused Then StatusText.BackColor = _clInputBackcolor
2709                     StatusText.Font = _fntInputFont
2710                     StatusText.ForeColor = _clInputFont
2711                 Catch ex As Exception
2712                     MessageBox.Show(ex.Message)
2713                 End Try
2714
2715                 _brsForeColorUnread.Dispose()
2716                 _brsForeColorReaded.Dispose()
2717                 _brsForeColorFav.Dispose()
2718                 _brsForeColorOWL.Dispose()
2719                 _brsForeColorRetweet.Dispose()
2720                 _brsForeColorUnread = New SolidBrush(_clUnread)
2721                 _brsForeColorReaded = New SolidBrush(_clReaded)
2722                 _brsForeColorFav = New SolidBrush(_clFav)
2723                 _brsForeColorOWL = New SolidBrush(_clOWL)
2724                 _brsForeColorRetweet = New SolidBrush(_clRetweet)
2725                 _brsBackColorMine.Dispose()
2726                 _brsBackColorAt.Dispose()
2727                 _brsBackColorYou.Dispose()
2728                 _brsBackColorAtYou.Dispose()
2729                 _brsBackColorAtFromTarget.Dispose()
2730                 _brsBackColorAtTo.Dispose()
2731                 _brsBackColorNone.Dispose()
2732                 _brsBackColorMine = New SolidBrush(_clSelf)
2733                 _brsBackColorAt = New SolidBrush(_clAtSelf)
2734                 _brsBackColorYou = New SolidBrush(_clTarget)
2735                 _brsBackColorAtYou = New SolidBrush(_clAtTarget)
2736                 _brsBackColorAtFromTarget = New SolidBrush(_clAtFromTarget)
2737                 _brsBackColorAtTo = New SolidBrush(_clAtTo)
2738                 _brsBackColorNone = New SolidBrush(_clListBackcolor)
2739                 Try
2740                     If SettingDialog.IsMonospace Then
2741                         detailHtmlFormatHeader = detailHtmlFormatMono1
2742                         detailHtmlFormatFooter = detailHtmlFormatMono7
2743                     Else
2744                         detailHtmlFormatHeader = detailHtmlFormat1
2745                         detailHtmlFormatFooter = detailHtmlFormat7
2746                     End If
2747                     detailHtmlFormatHeader += _fntDetail.Name + detailHtmlFormat2 + _fntDetail.Size.ToString() + detailHtmlFormat3 + _clDetail.R.ToString + "," + _clDetail.G.ToString + "," + _clDetail.B.ToString + detailHtmlFormat4 + _clDetailLink.R.ToString + "," + _clDetailLink.G.ToString + "," + _clDetailLink.B.ToString + detailHtmlFormat5 + _clDetailBackcolor.R.ToString + "," + _clDetailBackcolor.G.ToString + "," + _clDetailBackcolor.B.ToString
2748                     If SettingDialog.IsMonospace Then
2749                         detailHtmlFormatHeader += detailHtmlFormatMono6
2750                     Else
2751                         detailHtmlFormatHeader += detailHtmlFormat6
2752                     End If
2753                 Catch ex As Exception
2754                     ex.Data("Instance") = "Font"
2755                     ex.Data("IsTerminatePermission") = False
2756                     Throw
2757                 End Try
2758                 Try
2759                     _statuses.SetUnreadManage(SettingDialog.UnreadManage)
2760                 Catch ex As Exception
2761                     ex.Data("Instance") = "_statuses"
2762                     ex.Data("IsTerminatePermission") = False
2763                     Throw
2764                 End Try
2765
2766                 Try
2767                     For Each tb As TabPage In ListTab.TabPages
2768                         If SettingDialog.TabIconDisp Then
2769                             If _statuses.Tabs(tb.Text).UnreadCount = 0 Then
2770                                 tb.ImageIndex = -1
2771                             Else
2772                                 tb.ImageIndex = 0
2773                             End If
2774                         End If
2775                         If tb.Tag IsNot Nothing AndAlso tb.Controls.Count > 0 Then
2776                             DirectCast(tb.Tag, DetailsListView).Font = _fntReaded
2777                             DirectCast(tb.Tag, DetailsListView).BackColor = _clListBackcolor
2778                         End If
2779                     Next
2780                 Catch ex As Exception
2781                     ex.Data("Instance") = "ListTab(TabIconDisp no2)"
2782                     ex.Data("IsTerminatePermission") = False
2783                     Throw
2784                 End Try
2785                 If SettingDialog.UseAtIdSupplement AndAlso AtIdSupl Is Nothing Then
2786                     AtIdSupl = New AtIdSupplement(SettingAtIdList.Load().AtIdList)
2787                 End If
2788                 If Not SettingDialog.UseAtIdSupplement AndAlso AtIdSupl IsNot Nothing Then
2789                     AtIdSupl = Nothing
2790                 End If
2791                 SetMainWindowTitle()
2792                 SetNotifyIconText()
2793
2794                 _itemCache = Nothing
2795                 _postCache = Nothing
2796                 If _curList IsNot Nothing Then _curList.Refresh()
2797                 ListTab.Refresh()
2798             End SyncLock
2799         End If
2800
2801         Twitter.AccountState = ACCOUNT_STATE.Valid
2802
2803         Me.TopMost = SettingDialog.AlwaysTop
2804         SaveConfigsAll(False)
2805
2806         If chgUseApi AndAlso SettingDialog.OneWayLove Then doGetFollowersMenu(False) 'API使用を切り替えたら取り直し
2807     End Sub
2808
2809     Private Sub PostBrowser_Navigated(ByVal sender As Object, ByVal e As System.Windows.Forms.WebBrowserNavigatedEventArgs) Handles PostBrowser.Navigated
2810         If e.Url.AbsoluteUri <> "about:blank" Then
2811             DispSelectedPost()
2812             OpenUriAsync(e.Url.AbsoluteUri)
2813         End If
2814     End Sub
2815
2816     Private Sub PostBrowser_Navigating(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserNavigatingEventArgs) Handles PostBrowser.Navigating
2817         If e.Url.Scheme = "data" Then
2818             StatusLabelUrl.Text = PostBrowser.StatusText.Replace("&", "&&")
2819         ElseIf e.Url.AbsoluteUri <> "about:blank" Then
2820             e.Cancel = True
2821             OpenUriAsync(e.Url.AbsoluteUri)
2822         End If
2823     End Sub
2824
2825     Public Function AddNewTab(ByVal tabName As String, ByVal startup As Boolean, ByVal tabType As TabUsageType) As Boolean
2826         '重複チェック
2827         For Each tb As TabPage In ListTab.TabPages
2828             If tb.Text = tabName Then Return False
2829         Next
2830
2831         '新規タブ名チェック
2832         If tabName = My.Resources.AddNewTabText1 Then Return False
2833         If tabName <> ReplaceInvalidFilename(tabName) Then Return False
2834
2835         'タブタイプ重複チェック
2836         If Not startup Then
2837             If tabType = TabUsageType.DirectMessage OrElse _
2838                tabType = TabUsageType.Favorites OrElse _
2839                tabType = TabUsageType.Home OrElse _
2840                tabType = TabUsageType.Mentions Then
2841                 If _statuses.GetTabByType(tabType) IsNot Nothing Then Return False
2842             End If
2843         End If
2844         'Dim myTab As New TabStructure()
2845
2846         Dim _tabPage As TabPage = New TabPage
2847         Dim _listCustom As DetailsListView = New DetailsListView
2848         Dim _colHd1 As ColumnHeader = New ColumnHeader()  'アイコン
2849         Dim _colHd2 As ColumnHeader = New ColumnHeader()   'ニックネーム
2850         Dim _colHd3 As ColumnHeader = New ColumnHeader()   '本文
2851         Dim _colHd4 As ColumnHeader = New ColumnHeader()   '日付
2852         Dim _colHd5 As ColumnHeader = New ColumnHeader()   'ユーザID
2853         Dim _colHd6 As ColumnHeader = New ColumnHeader()   '未読
2854         Dim _colHd7 As ColumnHeader = New ColumnHeader()   'マーク&プロテクト
2855         Dim _colHd8 As ColumnHeader = New ColumnHeader()   'ソース
2856         'If Not _iconCol Then
2857         '_colHd2 = New ColumnHeader()
2858         '_colHd3 = New ColumnHeader()
2859         '_colHd4 = New ColumnHeader()
2860         '_colHd5 = New ColumnHeader()
2861         '_colHd6 = New ColumnHeader()
2862         '_colHd7 = New ColumnHeader()
2863         '_colHd8 = New ColumnHeader()
2864         '_colHd9 = New ColumnHeader()
2865         'End If
2866
2867         'If Not startup Then _section.ListElement.Add(New ListElement(tabName))
2868
2869         Dim cnt As Integer = ListTab.TabPages.Count
2870
2871         '''ToDo:Create and set controls follow tabtypes
2872
2873         Me.SplitContainer1.Panel1.SuspendLayout()
2874         Me.SplitContainer1.Panel2.SuspendLayout()
2875         Me.SplitContainer1.SuspendLayout()
2876         Me.ListTab.SuspendLayout()
2877         Me.SuspendLayout()
2878
2879         _tabPage.SuspendLayout()
2880
2881
2882
2883         ''' 検索関連の準備
2884         Dim pnl As New Panel
2885         Dim lbl As New Label
2886         Dim cmb As New ComboBox
2887         Dim btn As New Button
2888         pnl.SuspendLayout()
2889
2890         pnl.Controls.Add(cmb)
2891         pnl.Controls.Add(btn)
2892         pnl.Controls.Add(lbl)
2893         pnl.Name = "panel1"
2894         pnl.Dock = DockStyle.Top
2895         pnl.Height = cmb.Height
2896
2897         lbl.Text = "検索"
2898         lbl.Name = "label1"
2899         lbl.Dock = DockStyle.Left
2900         lbl.Width = 50
2901         lbl.Height = cmb.Height
2902         lbl.TextAlign = ContentAlignment.MiddleLeft
2903
2904         btn.Text = "button1"
2905         btn.Name = "button1"
2906         btn.UseVisualStyleBackColor = True
2907         btn.Dock = DockStyle.Right
2908
2909         cmb.Text = ""
2910         cmb.Dock = DockStyle.Fill
2911         cmb.Name = "combo1"
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925         Me.ListTab.Controls.Add(_tabPage)
2926         _tabPage.Controls.Add(_listCustom)
2927         _tabPage.Controls.Add(pnl)
2928         _tabPage.Location = New Point(4, 4)
2929         _tabPage.Name = "CTab" + cnt.ToString()
2930         _tabPage.Size = New Size(380, 260)
2931         _tabPage.TabIndex = 2 + cnt
2932         _tabPage.Text = tabName
2933         _tabPage.UseVisualStyleBackColor = True
2934
2935         _listCustom.AllowColumnReorder = True
2936         If Not _iconCol Then
2937             _listCustom.Columns.AddRange(New ColumnHeader() {_colHd1, _colHd2, _colHd3, _colHd4, _colHd5, _colHd6, _colHd7, _colHd8})
2938         Else
2939             _listCustom.Columns.AddRange(New ColumnHeader() {_colHd1, _colHd3})
2940         End If
2941         _listCustom.ContextMenuStrip = Me.ContextMenuStrip2
2942         _listCustom.Dock = DockStyle.Fill
2943         _listCustom.FullRowSelect = True
2944         _listCustom.HideSelection = False
2945         _listCustom.Location = New Point(0, 0)
2946         _listCustom.Margin = New Padding(0)
2947         _listCustom.Name = "CList" + Environment.TickCount.ToString()
2948         _listCustom.ShowItemToolTips = True
2949         _listCustom.Size = New Size(380, 260)
2950         _listCustom.TabIndex = 4                                   'これ大丈夫?
2951         _listCustom.UseCompatibleStateImageBehavior = False
2952         _listCustom.View = View.Details
2953         _listCustom.OwnerDraw = True
2954         _listCustom.VirtualMode = True
2955         _listCustom.Font = _fntReaded
2956         _listCustom.BackColor = _clListBackcolor
2957
2958         _listCustom.GridLines = SettingDialog.ShowGrid
2959
2960         AddHandler _listCustom.SelectedIndexChanged, AddressOf MyList_SelectedIndexChanged
2961         AddHandler _listCustom.MouseDoubleClick, AddressOf MyList_MouseDoubleClick
2962         AddHandler _listCustom.ColumnClick, AddressOf MyList_ColumnClick
2963         AddHandler _listCustom.DrawColumnHeader, AddressOf MyList_DrawColumnHeader
2964
2965         Select Case _iconSz
2966             Case 26, 48
2967                 AddHandler _listCustom.DrawItem, AddressOf MyList_DrawItem
2968             Case Else
2969                 AddHandler _listCustom.DrawItem, AddressOf MyList_DrawItemDefault
2970         End Select
2971
2972         'AddHandler _listCustom.Scrolled, AddressOf Mylist_Scrolled
2973         AddHandler _listCustom.MouseClick, AddressOf MyList_MouseClick
2974         AddHandler _listCustom.ColumnReordered, AddressOf MyList_ColumnReordered
2975         AddHandler _listCustom.ColumnWidthChanged, AddressOf MyList_ColumnWidthChanged
2976         AddHandler _listCustom.CacheVirtualItems, AddressOf MyList_CacheVirtualItems
2977         AddHandler _listCustom.RetrieveVirtualItem, AddressOf MyList_RetrieveVirtualItem
2978         AddHandler _listCustom.DrawSubItem, AddressOf MyList_DrawSubItem
2979
2980         _colHd1.Text = ""
2981         _colHd1.Width = 48
2982         'If Not _iconCol Then
2983         _colHd2.Text = My.Resources.AddNewTabText2
2984         _colHd2.Width = 80
2985         _colHd3.Text = My.Resources.AddNewTabText3
2986         _colHd3.Width = 300
2987         If SettingDialog.UseAPI Then
2988             _colHd4.Text = My.Resources.AddNewTabText4_2
2989         Else
2990             _colHd4.Text = My.Resources.AddNewTabText4
2991         End If
2992         _colHd4.Width = 50
2993         _colHd5.Text = My.Resources.AddNewTabText5
2994         _colHd5.Width = 50
2995         _colHd6.Text = ""
2996         _colHd6.Width = 16
2997         _colHd7.Text = ""
2998         _colHd7.Width = 16
2999         _colHd8.Text = "Source"
3000         _colHd8.Width = 50
3001         'End If
3002
3003         If (_statuses.Tabs.ContainsKey(tabName) AndAlso _statuses.Tabs(tabName).TabType = TabUsageType.Mentions) _
3004            OrElse Not _statuses.IsDefaultTab(tabName) Then
3005             TabDialog.AddTab(tabName)
3006         End If
3007
3008         _listCustom.SmallImageList = TIconSmallList
3009         '_listCustom.ListViewItemSorter = listViewItemSorter
3010         Dim dispOrder(7) As Integer
3011         If Not startup Then
3012             For i As Integer = 0 To _curList.Columns.Count - 1
3013                 For j As Integer = 0 To _curList.Columns.Count - 1
3014                     If _curList.Columns(j).DisplayIndex = i Then
3015                         dispOrder(i) = j
3016                         Exit For
3017                     End If
3018                 Next
3019             Next
3020             For i As Integer = 0 To _curList.Columns.Count - 1
3021                 _listCustom.Columns(i).Width = _curList.Columns(i).Width
3022                 _listCustom.Columns(dispOrder(i)).DisplayIndex = i
3023             Next
3024         Else
3025             If _iconCol Then
3026                 _listCustom.Columns(0).Width = _cfgLocal.Width1
3027                 _listCustom.Columns(1).Width = _cfgLocal.Width3
3028                 _listCustom.Columns(0).DisplayIndex = 0
3029                 _listCustom.Columns(1).DisplayIndex = 1
3030             Else
3031                 For i As Integer = 0 To 7
3032                     If _cfgLocal.DisplayIndex1 = i Then
3033                         dispOrder(i) = 0
3034                     ElseIf _cfgLocal.DisplayIndex2 = i Then
3035                         dispOrder(i) = 1
3036                     ElseIf _cfgLocal.DisplayIndex3 = i Then
3037                         dispOrder(i) = 2
3038                     ElseIf _cfgLocal.DisplayIndex4 = i Then
3039                         dispOrder(i) = 3
3040                     ElseIf _cfgLocal.DisplayIndex5 = i Then
3041                         dispOrder(i) = 4
3042                     ElseIf _cfgLocal.DisplayIndex6 = i Then
3043                         dispOrder(i) = 5
3044                     ElseIf _cfgLocal.DisplayIndex7 = i Then
3045                         dispOrder(i) = 6
3046                     ElseIf _cfgLocal.DisplayIndex8 = i Then
3047                         dispOrder(i) = 7
3048                     End If
3049                 Next
3050                 _listCustom.Columns(0).Width = _cfgLocal.Width1
3051                 _listCustom.Columns(1).Width = _cfgLocal.Width2
3052                 _listCustom.Columns(2).Width = _cfgLocal.Width3
3053                 _listCustom.Columns(3).Width = _cfgLocal.Width4
3054                 _listCustom.Columns(4).Width = _cfgLocal.Width5
3055                 _listCustom.Columns(5).Width = _cfgLocal.Width6
3056                 _listCustom.Columns(6).Width = _cfgLocal.Width7
3057                 _listCustom.Columns(7).Width = _cfgLocal.Width8
3058                 For i As Integer = 0 To 7
3059                     _listCustom.Columns(dispOrder(i)).DisplayIndex = i
3060                 Next
3061             End If
3062         End If
3063
3064
3065
3066
3067         pnl.ResumeLayout(False)
3068
3069
3070         _tabPage.ResumeLayout(False)
3071
3072         Me.SplitContainer1.Panel1.ResumeLayout(False)
3073         Me.SplitContainer1.Panel2.ResumeLayout(False)
3074         Me.SplitContainer1.ResumeLayout(False)
3075         Me.ListTab.ResumeLayout(False)
3076         Me.ResumeLayout(False)
3077         Me.PerformLayout()
3078         _tabPage.Tag = _listCustom
3079         Return True
3080     End Function
3081
3082     Public Function RemoveSpecifiedTab(ByVal TabName As String) As Boolean
3083         Dim idx As Integer = 0
3084         For idx = 0 To ListTab.TabPages.Count - 1
3085             If ListTab.TabPages(idx).Text = TabName Then Exit For
3086         Next
3087
3088         If _statuses.IsDefaultTab(TabName) Then Return False
3089
3090         Dim tmp As String = String.Format(My.Resources.RemoveSpecifiedTabText1, Environment.NewLine)
3091         If MessageBox.Show(tmp, My.Resources.RemoveSpecifiedTabText2, _
3092                          MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
3093             Return False
3094         End If
3095
3096         SetListProperty()   '他のタブに列幅等を反映
3097
3098         'オブジェクトインスタンスの削除
3099         Me.SplitContainer1.Panel1.SuspendLayout()
3100         Me.SplitContainer1.Panel2.SuspendLayout()
3101         Me.SplitContainer1.SuspendLayout()
3102         Me.ListTab.SuspendLayout()
3103         Me.SuspendLayout()
3104
3105         Dim _tabPage As TabPage = ListTab.TabPages(idx)
3106         Dim _listCustom As DetailsListView = DirectCast(_tabPage.Tag, DetailsListView)
3107         _tabPage.Tag = Nothing
3108
3109         _tabPage.SuspendLayout()
3110
3111         Me.ListTab.Controls.Remove(_tabPage)
3112         _tabPage.Controls.Remove(_listCustom)
3113         _listCustom.Columns.Clear()
3114         _listCustom.ContextMenuStrip = Nothing
3115
3116         RemoveHandler _listCustom.SelectedIndexChanged, AddressOf MyList_SelectedIndexChanged
3117         RemoveHandler _listCustom.MouseDoubleClick, AddressOf MyList_MouseDoubleClick
3118         RemoveHandler _listCustom.ColumnClick, AddressOf MyList_ColumnClick
3119         RemoveHandler _listCustom.DrawColumnHeader, AddressOf MyList_DrawColumnHeader
3120
3121         Select Case _iconSz
3122             Case 26, 48
3123                 RemoveHandler _listCustom.DrawItem, AddressOf MyList_DrawItem
3124             Case Else
3125                 RemoveHandler _listCustom.DrawItem, AddressOf MyList_DrawItemDefault
3126         End Select
3127
3128         'RemoveHandler _listCustom.Scrolled, AddressOf Mylist_Scrolled
3129         RemoveHandler _listCustom.MouseClick, AddressOf MyList_MouseClick
3130         RemoveHandler _listCustom.ColumnReordered, AddressOf MyList_ColumnReordered
3131         RemoveHandler _listCustom.ColumnWidthChanged, AddressOf MyList_ColumnWidthChanged
3132         RemoveHandler _listCustom.CacheVirtualItems, AddressOf MyList_CacheVirtualItems
3133         RemoveHandler _listCustom.RetrieveVirtualItem, AddressOf MyList_RetrieveVirtualItem
3134         RemoveHandler _listCustom.DrawSubItem, AddressOf MyList_DrawSubItem
3135
3136         TabDialog.RemoveTab(TabName)
3137
3138         _listCustom.SmallImageList = Nothing
3139         _listCustom.ListViewItemSorter = Nothing
3140
3141         'キャッシュのクリア
3142         If _curTab.Equals(_tabPage) Then
3143             _curTab = Nothing
3144             _curItemIndex = -1
3145             _curList = Nothing
3146             _curPost = Nothing
3147         End If
3148         _itemCache = Nothing
3149         _itemCacheIndex = -1
3150         _postCache = Nothing
3151
3152         _tabPage.ResumeLayout(False)
3153
3154         Me.SplitContainer1.Panel1.ResumeLayout(False)
3155         Me.SplitContainer1.Panel2.ResumeLayout(False)
3156         Me.SplitContainer1.ResumeLayout(False)
3157         Me.ListTab.ResumeLayout(False)
3158         Me.ResumeLayout(False)
3159         Me.PerformLayout()
3160
3161         _tabPage.Dispose()
3162         _listCustom.Dispose()
3163         _statuses.RemoveTab(TabName)
3164
3165         'SaveConfigsCommon()
3166         'SaveConfigsTab(False)
3167
3168         For Each tp As TabPage In ListTab.TabPages
3169             Dim lst As DetailsListView = DirectCast(tp.Tag, DetailsListView)
3170             If lst.VirtualListSize <> _statuses.Tabs(tp.Text).AllCount Then
3171                 lst.VirtualListSize = _statuses.Tabs(tp.Text).AllCount
3172             End If
3173         Next
3174         Return True
3175     End Function
3176
3177     Private Sub ListTab_Deselected(ByVal sender As Object, ByVal e As System.Windows.Forms.TabControlEventArgs) Handles ListTab.Deselected
3178         _itemCache = Nothing
3179         _itemCacheIndex = -1
3180         _postCache = Nothing
3181     End Sub
3182
3183     Private Sub ListTab_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseMove
3184         'タブのD&D
3185         Dim cpos As New Point(e.X, e.Y)
3186
3187         If e.Button = Windows.Forms.MouseButtons.Left AndAlso _tabDrag Then
3188             Dim tn As String = ""
3189             For i As Integer = 0 To ListTab.TabPages.Count - 1
3190                 Dim rect As Rectangle = ListTab.GetTabRect(i)
3191                 If rect.Left <= cpos.X AndAlso cpos.X <= rect.Right AndAlso _
3192                    rect.Top <= cpos.Y AndAlso cpos.Y <= rect.Bottom Then
3193                     tn = ListTab.TabPages(i).Text
3194                     Exit For
3195                 End If
3196             Next
3197
3198             If tn = "" Then Exit Sub
3199
3200             For Each tb As TabPage In ListTab.TabPages
3201                 If tb.Text = tn Then
3202                     ListTab.DoDragDrop(tb, DragDropEffects.All)
3203                     Exit For
3204                 End If
3205             Next
3206         Else
3207             _tabDrag = False
3208         End If
3209
3210         For i As Integer = 0 To ListTab.TabPages.Count - 1
3211             Dim rect As Rectangle = ListTab.GetTabRect(i)
3212             If rect.Left <= cpos.X And cpos.X <= rect.Right And _
3213                rect.Top <= cpos.Y And cpos.Y <= rect.Bottom Then
3214                 _rclickTabName = ListTab.TabPages(i).Text
3215                 Exit For
3216             End If
3217         Next
3218     End Sub
3219
3220     Private Sub ListTab_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListTab.SelectedIndexChanged
3221         '_curList.Refresh()
3222         DispSelectedPost()
3223         SetMainWindowTitle()
3224         SetStatusLabel()
3225     End Sub
3226
3227     Private Sub SetListProperty()
3228         '削除などで見つからない場合は処理せず
3229         If _curList Is Nothing Then Exit Sub
3230
3231         Dim dispOrder(_curList.Columns.Count - 1) As Integer
3232         For i As Integer = 0 To _curList.Columns.Count - 1
3233             For j As Integer = 0 To _curList.Columns.Count - 1
3234                 If _curList.Columns(j).DisplayIndex = i Then
3235                     dispOrder(i) = j
3236                     Exit For
3237                 End If
3238             Next
3239         Next
3240
3241         '列幅、列並びを他のタブに設定
3242         For Each tb As TabPage In ListTab.TabPages
3243             If Not tb.Equals(_curTab) Then
3244                 If tb.Tag IsNot Nothing AndAlso tb.Controls.Count > 0 Then
3245                     Dim lst As DetailsListView = DirectCast(tb.Tag, DetailsListView)
3246                     For i As Integer = 0 To lst.Columns.Count - 1
3247                         lst.Columns(dispOrder(i)).DisplayIndex = i
3248                         lst.Columns(i).Width = _curList.Columns(i).Width
3249                     Next
3250                 End If
3251             End If
3252         Next
3253     End Sub
3254
3255     Private Sub PostBrowser_StatusTextChanged(ByVal sender As Object, ByVal e As EventArgs) Handles PostBrowser.StatusTextChanged
3256         If PostBrowser.StatusText.StartsWith("http") OrElse PostBrowser.StatusText.StartsWith("ftp") _
3257                 OrElse PostBrowser.StatusText.StartsWith("data") Then
3258             StatusLabelUrl.Text = PostBrowser.StatusText.Replace("&", "&&")
3259         End If
3260         If PostBrowser.StatusText = "" Then
3261             SetStatusLabel()
3262         End If
3263     End Sub
3264
3265     Private Sub StatusText_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles StatusText.KeyPress
3266         If Not SettingDialog.UseAtIdSupplement OrElse AtIdSupl Is Nothing Then Exit Sub
3267         If e.KeyChar = "@" Then
3268             '@マーク
3269             AtIdSupl.ShowDialog()
3270             Me.TopMost = SettingDialog.AlwaysTop
3271             If AtIdSupl.inputId <> "" Then
3272                 Dim fHalf As String = ""
3273                 Dim eHalf As String = ""
3274                 Dim selStart As Integer = StatusText.SelectionStart
3275                 If selStart > 1 Then
3276                     fHalf = StatusText.Text.Substring(0, selStart)
3277                 End If
3278                 If selStart < StatusText.Text.Length Then
3279                     eHalf = StatusText.Text.Substring(selStart)
3280                 End If
3281                 StatusText.Text = fHalf + AtIdSupl.inputId + eHalf
3282                 StatusText.SelectionStart = selStart + AtIdSupl.inputId.Length
3283             Else
3284                 ''入力なし&Backspaceで戻ったら、入力欄の@も消す
3285                 'If AtIdSupl.isBack Then
3286                 '    Dim fHalf As String = ""
3287                 '    Dim eHalf As String = ""
3288                 '    Dim selStart As Integer = StatusText.SelectionStart
3289                 '    If selStart > 1 Then
3290                 '        fHalf = StatusText.Text.Substring(0, selStart - 1)
3291                 '    End If
3292                 '    If selStart < StatusText.Text.Length Then
3293                 '        eHalf = StatusText.Text.Substring(selStart)
3294                 '    End If
3295                 '    StatusText.Text = fHalf + eHalf
3296                 '    If selStart > 0 Then
3297                 '        StatusText.SelectionStart = selStart - 1
3298                 '    End If
3299                 'End If
3300             End If
3301             e.Handled = True
3302         End If
3303     End Sub
3304
3305     Private Sub StatusText_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles StatusText.KeyUp
3306         'スペースキーで未読ジャンプ
3307         If Not e.Alt AndAlso Not e.Control AndAlso Not e.Shift Then
3308             If e.KeyCode = Keys.Space OrElse e.KeyCode = Keys.ProcessKey Then
3309                 If StatusText.Text = " " OrElse StatusText.Text = " " Then
3310                     e.Handled = True
3311                     StatusText.Text = ""
3312                     JumpUnreadMenuItem_Click(Nothing, Nothing)
3313                 End If
3314             End If
3315         End If
3316         Me.StatusText_TextChanged(Nothing, Nothing)
3317     End Sub
3318
3319     Private Sub StatusText_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusText.TextChanged
3320         '文字数カウント
3321         Dim pLen As Integer = GetRestStatusCount(True, False)
3322         lblLen.Text = pLen.ToString()
3323         If pLen < 0 Then
3324             StatusText.ForeColor = Color.Red
3325         Else
3326             StatusText.ForeColor = _clInputFont
3327         End If
3328         If StatusText.Text = "" Then
3329             _reply_to_id = 0
3330             _reply_to_name = ""
3331         End If
3332     End Sub
3333
3334     Private Function GetRestStatusCount(ByVal isAuto As Boolean, ByVal isAddFooter As Boolean) As Integer
3335         '文字数カウント
3336         Dim pLen As Integer = 140 - StatusText.Text.Length
3337         If (isAuto AndAlso Not My.Computer.Keyboard.ShiftKeyDown) OrElse _
3338            (Not isAuto AndAlso isAddFooter) Then
3339             If SettingDialog.UseRecommendStatus Then
3340                 pLen -= SettingDialog.RecommendStatusText.Length
3341             ElseIf SettingDialog.Status.Length > 0 Then
3342                 pLen -= SettingDialog.Status.Length + 1
3343             End If
3344         End If
3345         Return pLen
3346     End Function
3347
3348     Private Sub MyList_CacheVirtualItems(ByVal sender As System.Object, ByVal e As System.Windows.Forms.CacheVirtualItemsEventArgs)
3349         If _itemCache IsNot Nothing AndAlso _
3350            e.StartIndex >= _itemCacheIndex AndAlso _
3351            e.EndIndex < _itemCacheIndex + _itemCache.Length AndAlso _
3352            _curList.Equals(sender) Then
3353             'If the newly requested cache is a subset of the old cache, 
3354             'no need to rebuild everything, so do nothing.
3355             Return
3356         End If
3357
3358         'Now we need to rebuild the cache.
3359         If _curList.Equals(sender) Then CreateCache(e.StartIndex, e.EndIndex)
3360     End Sub
3361
3362     Private Sub MyList_RetrieveVirtualItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.RetrieveVirtualItemEventArgs)
3363         If _itemCache IsNot Nothing AndAlso e.ItemIndex >= _itemCacheIndex AndAlso e.ItemIndex < _itemCacheIndex + _itemCache.Length AndAlso _curList.Equals(sender) Then
3364             'A cache hit, so get the ListViewItem from the cache instead of making a new one.
3365             e.Item = _itemCache(e.ItemIndex - _itemCacheIndex)
3366         Else
3367             'A cache miss, so create a new ListViewItem and pass it back.
3368             Dim tb As TabPage = DirectCast(DirectCast(sender, Tween.TweenCustomControl.DetailsListView).Parent, TabPage)
3369             Try
3370                 e.Item = CreateItem(tb, _
3371                                     _statuses.Item(tb.Text, e.ItemIndex), _
3372                                     e.ItemIndex)
3373             Catch ex As Exception
3374                 '不正な要求に対する間に合わせの応答
3375                 Dim sitem() As String = {"", "", "", "", "", "", "", ""}
3376                 e.Item = New ListViewItem(sitem, -1)
3377             End Try
3378         End If
3379     End Sub
3380
3381     Private Sub CreateCache(ByVal StartIndex As Integer, ByVal EndIndex As Integer)
3382         Try
3383             'キャッシュ要求(要求範囲±30を作成)
3384             StartIndex -= 30
3385             If StartIndex < 0 Then StartIndex = 0
3386             EndIndex += 30
3387             If EndIndex >= _statuses.Tabs(_curTab.Text).AllCount Then EndIndex = _statuses.Tabs(_curTab.Text).AllCount - 1
3388             _postCache = _statuses.Item(_curTab.Text, StartIndex, EndIndex) '配列で取得
3389             _itemCacheIndex = StartIndex
3390
3391             _itemCache = New ListViewItem(_postCache.Length - 1) {}
3392             For i As Integer = 0 To _postCache.Length - 1
3393                 _itemCache(i) = CreateItem(_curTab, _postCache(i), StartIndex + i)
3394             Next i
3395         Catch ex As Exception
3396             'キャッシュ要求が実データとずれるため(イベントの遅延?)
3397             _postCache = Nothing
3398             _itemCache = Nothing
3399         End Try
3400     End Sub
3401
3402     Private Function CreateItem(ByVal Tab As TabPage, ByVal Post As PostClass, ByVal Index As Integer) As ListViewItem
3403         Dim mk As String = ""
3404         If Post.IsMark Then mk += "♪"
3405         If Post.IsProtect Then mk += "Ю"
3406         If Post.InReplyToId > 0 Then mk += "⇒"
3407         Dim sitem() As String = {"", Post.Nickname, Post.Data, Post.PDate.ToString(SettingDialog.DateTimeFormat), Post.Name, "", mk, Post.Source}
3408         Dim itm As ListViewItem = New ListViewItem(sitem, Post.ImageIndex)
3409         Dim read As Boolean = Post.IsRead
3410         '未読管理していなかったら既読として扱う
3411         If Not _statuses.Tabs(Tab.Text).UnreadManage OrElse _
3412            Not SettingDialog.UnreadManage Then read = True
3413         ChangeItemStyleRead(read, itm, Post, Nothing)
3414         If Tab.Equals(_curTab) Then ColorizeList(itm, Index)
3415         Return itm
3416     End Function
3417
3418     Private Sub MyList_DrawColumnHeader(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs)
3419         e.DrawDefault = True
3420     End Sub
3421
3422     Private Sub MyList_DrawItemDefault(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawListViewItemEventArgs)
3423         e.DrawDefault = True
3424     End Sub
3425
3426     Private Sub MyList_DrawItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawListViewItemEventArgs)
3427         'アイコンサイズ26,48はオーナードロー(DrawSubItem発生させる)
3428         If e.State = 0 Then Exit Sub
3429         e.DrawDefault = False
3430         If Not e.Item.Selected Then     'e.ItemStateでうまく判定できない???
3431             Dim brs2 As SolidBrush = Nothing
3432             Select Case e.Item.BackColor
3433                 Case _clSelf
3434                     brs2 = _brsBackColorMine
3435                 Case _clAtSelf
3436                     brs2 = _brsBackColorAt
3437                 Case _clTarget
3438                     brs2 = _brsBackColorYou
3439                 Case _clAtTarget
3440                     brs2 = _brsBackColorAtYou
3441                 Case _clAtFromTarget
3442                     brs2 = _brsBackColorAtFromTarget
3443                 Case _clAtTo
3444                     brs2 = _brsBackColorAtTo
3445                 Case Else
3446                     brs2 = _brsBackColorNone
3447             End Select
3448             e.Graphics.FillRectangle(brs2, e.Bounds)
3449         Else
3450             '選択中の行
3451             If DirectCast(sender, Windows.Forms.Control).Focused Then
3452                 e.Graphics.FillRectangle(_brsHighLight, e.Bounds)
3453             Else
3454                 e.Graphics.FillRectangle(_brsDeactiveSelection, e.Bounds)
3455             End If
3456         End If
3457         If (e.State And ListViewItemStates.Focused) = ListViewItemStates.Focused Then e.DrawFocusRectangle()
3458     End Sub
3459
3460     Private Sub MyList_DrawSubItem(ByVal sender As Object, ByVal e As DrawListViewSubItemEventArgs)
3461         If e.ItemState = 0 Then Exit Sub
3462         If e.ColumnIndex > 0 Then
3463             Dim rct As RectangleF = e.Bounds
3464             Dim rctB As RectangleF = e.Bounds
3465             rct.Width = e.Header.Width
3466             rctB.Width = e.Header.Width
3467             If _iconCol Then rct.Height = e.Item.Font.Height
3468             'アイコン以外の列
3469             If Not e.Item.Selected Then     'e.ItemStateでうまく判定できない???
3470                 '選択されていない行
3471                 '文字色
3472                 Dim brs As SolidBrush = Nothing
3473                 Dim flg As Boolean = False
3474                 Select Case e.Item.ForeColor
3475                     Case _clUnread
3476                         brs = _brsForeColorUnread
3477                     Case _clReaded
3478                         brs = _brsForeColorReaded
3479                     Case _clFav
3480                         brs = _brsForeColorFav
3481                     Case _clOWL
3482                         brs = _brsForeColorOWL
3483                     Case _clRetweet
3484                         brs = _brsForeColorRetweet
3485                     Case Else
3486                         brs = New SolidBrush(e.Item.ForeColor)
3487                         flg = True
3488                 End Select
3489                 If rct.Width > 0 Then
3490                     If _iconCol Then
3491                         Dim fnt As New Font(e.Item.Font, FontStyle.Bold)
3492                         e.Graphics.DrawString(System.Environment.NewLine + e.Item.SubItems(2).Text, e.Item.Font, brs, rctB, sf)
3493                         e.Graphics.DrawString(e.Item.SubItems(4).Text + " / " + e.Item.SubItems(1).Text + " (" + e.Item.SubItems(3).Text + ") <" + e.Item.SubItems(5).Text + e.Item.SubItems(6).Text + "> from " + e.Item.SubItems(7).Text, fnt, brs, rct, sf)
3494                         fnt.Dispose()
3495                     Else
3496                         e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, brs, rct, sf)
3497                     End If
3498                 End If
3499                 If flg Then brs.Dispose()
3500             Else
3501                 If rct.Width > 0 Then
3502                     '選択中の行
3503                     Dim fnt As New Font(e.Item.Font, FontStyle.Bold)
3504                     If DirectCast(sender, Windows.Forms.Control).Focused Then
3505                         If _iconCol Then
3506                             e.Graphics.DrawString(System.Environment.NewLine + e.Item.SubItems(2).Text, e.Item.Font, _brsHighLightText, rctB, sf)
3507                             e.Graphics.DrawString(e.Item.SubItems(4).Text + " / " + e.Item.SubItems(1).Text + " (" + e.Item.SubItems(3).Text + ") <" + e.Item.SubItems(5).Text + e.Item.SubItems(6).Text + "> from " + e.Item.SubItems(7).Text, fnt, _brsHighLightText, rct, sf)
3508                         Else
3509                             e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, _brsHighLightText, rct, sf)
3510                         End If
3511                     Else
3512                         If _iconCol Then
3513                             e.Graphics.DrawString(System.Environment.NewLine + e.Item.SubItems(2).Text, e.Item.Font, _brsForeColorUnread, rctB, sf)
3514                             e.Graphics.DrawString(e.Item.SubItems(4).Text + " / " + e.Item.SubItems(1).Text + " (" + e.Item.SubItems(3).Text + ") <" + e.Item.SubItems(5).Text + e.Item.SubItems(6).Text + "> from " + e.Item.SubItems(7).Text, fnt, _brsForeColorUnread, rct, sf)
3515                         Else
3516                             e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, _brsForeColorUnread, rct, sf)
3517                         End If
3518                     End If
3519                     fnt.Dispose()
3520                 End If
3521             End If
3522         Else
3523             'アイコン列はデフォルト描画
3524             e.DrawDefault = True
3525         End If
3526     End Sub
3527
3528     Private Sub DoTabSearch(ByVal _word As String, _
3529                             ByVal CaseSensitive As Boolean, _
3530                             ByVal UseRegex As Boolean, _
3531                             ByVal SType As SEARCHTYPE)
3532         Dim cidx As Integer = 0
3533         Dim fnd As Boolean = False
3534         Dim toIdx As Integer
3535         Dim stp As Integer = 1
3536
3537         If _curList.VirtualListSize = 0 Then
3538             MessageBox.Show(My.Resources.DoTabSearchText2, My.Resources.DoTabSearchText3, MessageBoxButtons.OK, MessageBoxIcon.Information)
3539         End If
3540
3541         If _curList.SelectedIndices.Count > 0 Then
3542             cidx = _curList.SelectedIndices(0)
3543         End If
3544         toIdx = _curList.VirtualListSize - 1
3545
3546         Select Case SType
3547             Case SEARCHTYPE.DialogSearch    'ダイアログからの検索
3548                 If _curList.SelectedIndices.Count > 0 Then
3549                     cidx = _curList.SelectedIndices(0)
3550                 Else
3551                     cidx = 0
3552                 End If
3553             Case SEARCHTYPE.NextSearch      '次を検索
3554                 If _curList.SelectedIndices.Count > 0 Then
3555                     cidx = _curList.SelectedIndices(0) + 1
3556                     If cidx > toIdx Then cidx = toIdx
3557                 Else
3558                     cidx = 0
3559                 End If
3560             Case SEARCHTYPE.PrevSearch      '前を検索
3561                 If _curList.SelectedIndices.Count > 0 Then
3562                     cidx = _curList.SelectedIndices(0) - 1
3563                     If cidx < 0 Then cidx = 0
3564                 Else
3565                     cidx = toIdx
3566                 End If
3567                 toIdx = 0
3568                 stp = -1
3569         End Select
3570
3571         Dim regOpt As RegexOptions = RegexOptions.None
3572         Dim fndOpt As StringComparison = StringComparison.Ordinal
3573         If Not CaseSensitive Then
3574             regOpt = RegexOptions.IgnoreCase
3575             fndOpt = StringComparison.OrdinalIgnoreCase
3576         End If
3577         Try
3578 RETRY:
3579             If UseRegex Then
3580                 ' 正規表現検索
3581                 Dim _search As Regex
3582                 Try
3583                     _search = New Regex(_word)
3584                     For idx As Integer = cidx To toIdx Step stp
3585                         Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
3586                         If _search.IsMatch(post.Nickname, regOpt) _
3587                             OrElse _search.IsMatch(post.Data, regOpt) _
3588                             OrElse _search.IsMatch(post.Name, regOpt) _
3589                         Then
3590                             SelectListItem(_curList, idx)
3591                             _curList.EnsureVisible(idx)
3592                             Exit Sub
3593                         End If
3594                     Next
3595                 Catch ex As ArgumentException
3596                     MsgBox(My.Resources.DoTabSearchText1, MsgBoxStyle.Critical)
3597                     Exit Sub
3598                 End Try
3599             Else
3600                 ' 通常検索
3601                 For idx As Integer = cidx To toIdx Step stp
3602                     Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
3603                     If post.Nickname.IndexOf(_word, fndOpt) > -1 _
3604                         OrElse post.Data.IndexOf(_word, fndOpt) > -1 _
3605                         OrElse post.Name.IndexOf(_word, fndOpt) > -1 _
3606                     Then
3607                         SelectListItem(_curList, idx)
3608                         _curList.EnsureVisible(idx)
3609                         Exit Sub
3610                     End If
3611                 Next
3612             End If
3613
3614             If Not fnd Then
3615                 Select Case SType
3616                     Case SEARCHTYPE.DialogSearch, SEARCHTYPE.NextSearch
3617                         toIdx = cidx
3618                         cidx = 0
3619                     Case SEARCHTYPE.PrevSearch
3620                         toIdx = cidx
3621                         cidx = _curList.Items.Count - 1
3622                 End Select
3623                 fnd = True
3624                 GoTo RETRY
3625             End If
3626         Catch ex As ArgumentOutOfRangeException
3627
3628         End Try
3629         MessageBox.Show(My.Resources.DoTabSearchText2, My.Resources.DoTabSearchText3, MessageBoxButtons.OK, MessageBoxIcon.Information)
3630     End Sub
3631
3632     Private Sub MenuItemSubSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemSubSearch.Click
3633         '検索メニュー
3634         SearchDialog.Owner = Me
3635         If SearchDialog.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
3636             Me.TopMost = SettingDialog.AlwaysTop
3637             Exit Sub
3638         End If
3639         Me.TopMost = SettingDialog.AlwaysTop
3640
3641         If SearchDialog.SWord <> "" Then
3642             DoTabSearch(SearchDialog.SWord, _
3643                         SearchDialog.CheckCaseSensitive, _
3644                         SearchDialog.CheckRegex, _
3645                         SEARCHTYPE.DialogSearch)
3646         End If
3647     End Sub
3648
3649     Private Sub MenuItemSearchNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemSearchNext.Click
3650         '次を検索
3651         If SearchDialog.SWord = "" Then
3652             If SearchDialog.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
3653                 Me.TopMost = SettingDialog.AlwaysTop
3654                 Exit Sub
3655             End If
3656             Me.TopMost = SettingDialog.AlwaysTop
3657             If SearchDialog.SWord = "" Then Exit Sub
3658
3659             DoTabSearch(SearchDialog.SWord, _
3660                         SearchDialog.CheckCaseSensitive, _
3661                         SearchDialog.CheckRegex, _
3662                         SEARCHTYPE.DialogSearch)
3663         Else
3664             DoTabSearch(SearchDialog.SWord, _
3665                         SearchDialog.CheckCaseSensitive, _
3666                         SearchDialog.CheckRegex, _
3667                         SEARCHTYPE.NextSearch)
3668         End If
3669     End Sub
3670
3671     Private Sub MenuItemSearchPrev_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemSearchPrev.Click
3672         '前を検索
3673         If SearchDialog.SWord = "" Then
3674             If SearchDialog.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
3675                 Me.TopMost = SettingDialog.AlwaysTop
3676                 Exit Sub
3677             End If
3678             Me.TopMost = SettingDialog.AlwaysTop
3679             If SearchDialog.SWord = "" Then Exit Sub
3680         End If
3681
3682         DoTabSearch(SearchDialog.SWord, _
3683                     SearchDialog.CheckCaseSensitive, _
3684                     SearchDialog.CheckRegex, _
3685                     SEARCHTYPE.PrevSearch)
3686     End Sub
3687
3688     Private Sub AboutMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AboutMenuItem.Click
3689         TweenAboutBox.ShowDialog()
3690         Me.TopMost = SettingDialog.AlwaysTop
3691     End Sub
3692
3693     Private Sub JumpUnreadMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles JumpUnreadMenuItem.Click
3694         Dim bgnIdx As Integer = ListTab.TabPages.IndexOf(_curTab)
3695         Dim idx As Integer = -1
3696         Dim lst As DetailsListView = Nothing
3697
3698         '現在タブから最終タブまで探索
3699         For i As Integer = bgnIdx To ListTab.TabPages.Count - 1
3700             '未読Index取得
3701             idx = _statuses.GetOldestUnreadId(ListTab.TabPages(i).Text)
3702             If idx > -1 Then
3703                 ListTab.SelectedIndex = i
3704                 lst = DirectCast(ListTab.TabPages(i).Tag, DetailsListView)
3705                 Exit For
3706             End If
3707         Next
3708
3709         '未読みつからず&現在タブが先頭ではなかったら、先頭タブから現在タブの手前まで探索
3710         If idx = -1 AndAlso bgnIdx > 0 Then
3711             For i As Integer = 0 To bgnIdx - 1
3712                 idx = _statuses.GetOldestUnreadId(ListTab.TabPages(i).Text)
3713                 If idx > -1 Then
3714                     ListTab.SelectedIndex = i
3715                     lst = DirectCast(ListTab.TabPages(i).Tag, DetailsListView)
3716                     Exit For
3717                 End If
3718             Next
3719         End If
3720
3721         '全部調べたが未読見つからず→先頭タブの最新発言へ
3722         If idx = -1 Then
3723             ListTab.SelectedIndex = 0
3724             lst = DirectCast(ListTab.TabPages(0).Tag, DetailsListView)
3725             If _statuses.SortOrder = SortOrder.Ascending Then
3726                 idx = lst.VirtualListSize - 1
3727             Else
3728                 idx = 0
3729             End If
3730         End If
3731
3732         If lst.VirtualListSize > 0 AndAlso idx > -1 AndAlso lst.VirtualListSize > idx Then
3733             SelectListItem(lst, idx)
3734             If _statuses.SortMode = IdComparerClass.ComparerMode.Id Then
3735                 If _statuses.SortOrder = SortOrder.Ascending AndAlso lst.Items(idx).Position.Y > lst.ClientSize.Height - _iconSz - 10 OrElse _
3736                    _statuses.SortOrder = SortOrder.Descending AndAlso lst.Items(idx).Position.Y < _iconSz + 10 Then
3737                     MoveTop()
3738                 Else
3739                     lst.EnsureVisible(idx)
3740                 End If
3741             Else
3742                 lst.EnsureVisible(idx)
3743             End If
3744         End If
3745         lst.Focus()
3746     End Sub
3747
3748     Private Sub StatusOpenMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusOpenMenuItem.Click
3749         If _curList.SelectedIndices.Count > 0 AndAlso _statuses.Tabs(_curTab.Text).TabType <> TabUsageType.DirectMessage Then
3750             Dim post As PostClass = _statuses.Item(_curTab.Text, _curList.SelectedIndices(0))
3751             If post.RetweetedId = 0 Then
3752                 OpenUriAsync("http://twitter.com/" + post.Name + "/status/" + post.Id.ToString)
3753             Else
3754                 OpenUriAsync("http://twitter.com/" + post.Name + "/status/" + post.RetweetedId.ToString)
3755             End If
3756         End If
3757     End Sub
3758
3759     Private Sub FavorareMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles FavorareMenuItem.Click
3760         If _curList.SelectedIndices.Count > 0 Then
3761             Dim post As PostClass = _statuses.Item(_curTab.Text, _curList.SelectedIndices(0))
3762             OpenUriAsync("http://favotter.matope.com/user.php?user=" + post.Name)
3763         End If
3764     End Sub
3765
3766     Private Sub VerUpMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles VerUpMenuItem.Click
3767         CheckNewVersion()
3768     End Sub
3769
3770     Private Sub RunTweenUp()
3771
3772         Dim pinfo As New ProcessStartInfo
3773         pinfo.UseShellExecute = True
3774         pinfo.WorkingDirectory = Application.StartupPath
3775         pinfo.FileName = Path.Combine(Application.StartupPath(), "TweenUp.exe")
3776         Try
3777             Process.Start(pinfo)
3778         Catch ex As Exception
3779             MsgBox("Failed to execute TweenUp.exe.")
3780         End Try
3781     End Sub
3782
3783     Private Sub CheckNewVersion(Optional ByVal startup As Boolean = False)
3784         Dim retMsg As String = ""
3785         Dim strVer As String = ""
3786         Dim strDetail As String = ""
3787         Dim forceUpdate As Boolean = My.Computer.Keyboard.ShiftKeyDown
3788
3789         Try
3790             retMsg = Twitter.GetVersionInfo()
3791         Catch ex As Exception
3792             StatusLabel.Text = My.Resources.CheckNewVersionText9
3793             If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText10, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
3794             Exit Sub
3795         End Try
3796         If retMsg.Length > 0 Then
3797             strVer = retMsg.Substring(0, 4)
3798             If retMsg.Length > 4 Then
3799                 strDetail = retMsg.Substring(5).Trim
3800             End If
3801             If strVer.CompareTo(fileVersion.Replace(".", "")) > 0 Then
3802                 Dim tmp As String = String.Format(My.Resources.CheckNewVersionText3, strVer)
3803                 Using dialogAsShieldicon As New DialogAsShieldIcon
3804                     If dialogAsShieldicon.Show(tmp, strDetail, My.Resources.CheckNewVersionText1, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
3805                         retMsg = Twitter.GetTweenBinary(strVer)
3806                         If retMsg.Length = 0 Then
3807                             retMsg = Twitter.GetTweenUpBinary()
3808                             If retMsg.Length = 0 Then
3809                                 RunTweenUp()
3810                                 'If startup Then
3811                                 '    Application.Exit()
3812                                 'Else
3813                                 _endingFlag = True
3814                                 dialogAsShieldicon.Dispose()
3815                                 Me.Close()
3816                                 'End If
3817                                 Exit Sub
3818                             Else
3819                                 If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText4 + System.Environment.NewLine + retMsg, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
3820                             End If
3821                         Else
3822                             If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText5 + System.Environment.NewLine + retMsg, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
3823                         End If
3824                     End If
3825                     dialogAsShieldicon.Dispose()
3826                 End Using
3827             Else
3828                 If forceUpdate Then
3829                     Dim tmp As String = String.Format(My.Resources.CheckNewVersionText6, strVer)
3830                     Using dialogAsShieldicon As New DialogAsShieldIcon
3831                         If dialogAsShieldicon.Show(tmp, strDetail, My.Resources.CheckNewVersionText1, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
3832                             retMsg = Twitter.GetTweenBinary(strVer)
3833                             If retMsg.Length = 0 Then
3834                                 retMsg = Twitter.GetTweenUpBinary()
3835                                 If retMsg.Length = 0 Then
3836                                     RunTweenUp()
3837                                     'If startup Then
3838                                     '    Application.Exit()
3839                                     'Else
3840                                     _endingFlag = True
3841                                     dialogAsShieldicon.Dispose()
3842                                     Me.Close()
3843                                     'End If
3844                                     Exit Sub
3845                                 Else
3846                                     If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText4 + System.Environment.NewLine + retMsg, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
3847                                 End If
3848                             Else
3849                                 If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText5 + System.Environment.NewLine + retMsg, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
3850                             End If
3851                         End If
3852                         dialogAsShieldicon.Dispose()
3853                     End Using
3854                 ElseIf Not startup Then
3855                     MessageBox.Show(My.Resources.CheckNewVersionText7 + fileVersion.Replace(".", "") + My.Resources.CheckNewVersionText8 + strVer, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Information)
3856                 End If
3857             End If
3858         Else
3859             StatusLabel.Text = My.Resources.CheckNewVersionText9
3860             If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText10, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
3861         End If
3862     End Sub
3863
3864     Private Sub TimerColorize_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerColorize.Tick
3865         If TimerColorize.Enabled = False Then Exit Sub
3866
3867         TimerColorize.Stop()
3868         TimerColorize.Enabled = False
3869         TimerColorize.Interval = 200
3870         DispSelectedPost()
3871         '件数関連の場合、タイトル即時書き換え
3872         If SettingDialog.DispLatestPost <> DispTitleEnum.None AndAlso _
3873            SettingDialog.DispLatestPost <> DispTitleEnum.Post AndAlso _
3874            SettingDialog.DispLatestPost <> DispTitleEnum.Ver Then
3875             SetMainWindowTitle()
3876         End If
3877         If Not StatusLabelUrl.Text.StartsWith("http") Then SetStatusLabel()
3878         For Each tb As TabPage In ListTab.TabPages
3879             If _statuses.Tabs(tb.Text).UnreadCount = 0 Then
3880                 If SettingDialog.TabIconDisp Then
3881                     If tb.ImageIndex = 0 Then tb.ImageIndex = -1
3882                 End If
3883             End If
3884         Next
3885         If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
3886     End Sub
3887
3888     Private Sub DispSelectedPost()
3889
3890         If _curList.SelectedIndices.Count = 0 OrElse _curPost Is Nothing Then Exit Sub
3891
3892         Dim dTxt As String = detailHtmlFormatHeader + _curPost.OriginalData + detailHtmlFormatFooter
3893         If _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage AndAlso _curPost.IsOwl Then
3894             NameLabel.Text = "DM TO -> "
3895         ElseIf _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage Then
3896             NameLabel.Text = "DM FROM <- "
3897         Else
3898             NameLabel.Text = ""
3899         End If
3900         NameLabel.Text += _curPost.Name + "/" + _curPost.Nickname
3901         If Not String.IsNullOrEmpty(_curPost.RetweetedBy) Then
3902             NameLabel.Text += " (RT:" + _curPost.RetweetedBy + ")"
3903         End If
3904         'If UserPicture.Image IsNot Nothing Then UserPicture.Image.Dispose()
3905         If _curPost.ImageIndex > -1 Then
3906             UserPicture.Image = TIconDic(_curPost.ImageUrl)
3907         Else
3908             UserPicture.Image = Nothing
3909         End If
3910         'UserPicture.Refresh()
3911
3912         NameLabel.ForeColor = System.Drawing.SystemColors.ControlText
3913         DateTimeLabel.Text = _curPost.PDate.ToString()
3914         If _curPost.IsOwl AndAlso (SettingDialog.OneWayLove OrElse _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage) Then NameLabel.ForeColor = _clOWL
3915         If _curPost.RetweetedId > 0 Then NameLabel.ForeColor = _clRetweet
3916         If _curPost.IsFav Then NameLabel.ForeColor = _clFav
3917
3918         If DumpPostClassToolStripMenuItem.Checked Then
3919             Dim sb As New StringBuilder(512)
3920
3921             sb.Append("-----Start PostClass Dump<br>")
3922             sb.AppendFormat("Data           : {0}<br>", _curPost.Data)
3923             sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.Data)
3924             sb.AppendFormat("Id             : {0}<br>", _curPost.Id.ToString)
3925             sb.AppendFormat("ImageIndex     : {0}<br>", _curPost.ImageIndex.ToString)
3926             sb.AppendFormat("ImageUrl       : {0}<br>", _curPost.ImageUrl)
3927             sb.AppendFormat("InReplyToId    : {0}<br>", _curPost.InReplyToId.ToString)
3928             sb.AppendFormat("InReplyToUser  : {0}<br>", _curPost.InReplyToUser)
3929             sb.AppendFormat("IsDM           : {0}<br>", _curPost.IsDm.ToString)
3930             sb.AppendFormat("IsFav          : {0}<br>", _curPost.IsFav.ToString)
3931             sb.AppendFormat("IsMark         : {0}<br>", _curPost.IsMark.ToString)
3932             sb.AppendFormat("IsMe           : {0}<br>", _curPost.IsMe.ToString)
3933             sb.AppendFormat("IsOwl          : {0}<br>", _curPost.IsOwl.ToString)
3934             sb.AppendFormat("IsProtect      : {0}<br>", _curPost.IsProtect.ToString)
3935             sb.AppendFormat("IsRead         : {0}<br>", _curPost.IsRead.ToString)
3936             sb.AppendFormat("IsReply        : {0}<br>", _curPost.IsReply.ToString)
3937
3938             For Each nm As String In _curPost.ReplyToList
3939                 sb.AppendFormat("ReplyToList    : {0}<br>", nm)
3940             Next
3941
3942             sb.AppendFormat("Name           : {0}<br>", _curPost.Name)
3943             sb.AppendFormat("NickName       : {0}<br>", _curPost.Nickname)
3944             sb.AppendFormat("OriginalData   : {0}<br>", _curPost.OriginalData)
3945             sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.OriginalData)
3946             sb.AppendFormat("PDate          : {0}<br>", _curPost.PDate.ToString)
3947             sb.AppendFormat("Source         : {0}<br>", _curPost.Source)
3948             sb.Append("-----End PostClass Dump<br>")
3949
3950             PostBrowser.Visible = False
3951             PostBrowser.DocumentText = detailHtmlFormatHeader + sb.ToString + detailHtmlFormatFooter
3952             PostBrowser.Visible = True
3953         Else
3954             Try
3955                 If PostBrowser.DocumentText <> dTxt Then
3956                     PostBrowser.Visible = False
3957                     PostBrowser.DocumentText = dTxt
3958                 End If
3959             Catch ex As System.Runtime.InteropServices.COMException
3960                 '原因不明
3961             Finally
3962                 PostBrowser.Visible = True
3963             End Try
3964         End If
3965     End Sub
3966
3967     Private Sub MatomeMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MatomeMenuItem.Click
3968         OpenUriAsync("http://sourceforge.jp/projects/tween/wiki/FrontPage")
3969     End Sub
3970
3971     Private Sub ListTab_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles ListTab.KeyDown
3972         If e.Modifiers = Keys.None Then
3973             ' ModifierKeyが押されていない場合
3974             If e.KeyCode = Keys.N OrElse e.KeyCode = Keys.Right Then
3975                 e.Handled = True
3976                 e.SuppressKeyPress = True
3977                 GoRelPost(True)
3978                 Exit Sub
3979             End If
3980             If e.KeyCode = Keys.P OrElse e.KeyCode = Keys.Left Then
3981                 e.Handled = True
3982                 e.SuppressKeyPress = True
3983                 GoRelPost(False)
3984                 Exit Sub
3985             End If
3986             If e.KeyCode = Keys.OemPeriod Then
3987                 e.Handled = True
3988                 e.SuppressKeyPress = True
3989                 GoAnchor()
3990                 Exit Sub
3991             End If
3992             _anchorFlag = False
3993             If e.KeyCode = Keys.Space OrElse e.KeyCode = Keys.ProcessKey Then
3994                 e.Handled = True
3995                 e.SuppressKeyPress = True
3996                 JumpUnreadMenuItem_Click(Nothing, Nothing)
3997             End If
3998             If e.KeyCode = Keys.Enter OrElse e.KeyCode = Keys.Return Then
3999                 e.Handled = True
4000                 e.SuppressKeyPress = True
4001                 MakeReplyOrDirectStatus()
4002             End If
4003             If e.KeyCode = Keys.L Then
4004                 e.Handled = True
4005                 e.SuppressKeyPress = True
4006                 GoPost(True)
4007             End If
4008             If e.KeyCode = Keys.H Then
4009                 e.Handled = True
4010                 e.SuppressKeyPress = True
4011                 GoPost(False)
4012             End If
4013             If e.KeyCode = Keys.Z Or e.KeyCode = Keys.Oemcomma Then
4014                 e.Handled = True
4015                 e.SuppressKeyPress = True
4016                 MoveTop()
4017             End If
4018             If e.KeyCode = Keys.R Then
4019                 e.Handled = True
4020                 e.SuppressKeyPress = True
4021                 DoRefresh()
4022             End If
4023             If e.KeyCode = Keys.S Then
4024                 e.Handled = True
4025                 e.SuppressKeyPress = True
4026                 SendKeys.Send("^{PGDN}")
4027             End If
4028             If e.KeyCode = Keys.A Then
4029                 e.Handled = True
4030                 e.SuppressKeyPress = True
4031                 SendKeys.Send("^{PGUP}")
4032             End If
4033             'If e.KeyCode = Keys.OemQuestion Then
4034             '    e.Handled = True
4035             '    e.SuppressKeyPress = True
4036             '    MenuItemSubSearch_Click(Nothing, Nothing)   '/検索
4037             'End If
4038             If e.KeyCode = Keys.F Then
4039                 e.Handled = True
4040                 e.SuppressKeyPress = True
4041                 SendKeys.Send("{PGDN}")
4042             End If
4043             If e.KeyCode = Keys.B Then
4044                 e.Handled = True
4045                 e.SuppressKeyPress = True
4046                 SendKeys.Send("{PGUP}")
4047             End If
4048         End If
4049         _anchorFlag = False
4050         If e.Control AndAlso Not e.Alt AndAlso Not e.Shift Then
4051             ' CTRLキーが押されている場合
4052             If e.KeyCode = Keys.Home OrElse e.KeyCode = Keys.End Then
4053                 TimerColorize.Stop()
4054                 TimerColorize.Start()
4055             End If
4056             If e.KeyCode = Keys.N Then SendKeys.Send("^{PGDN}")
4057             If e.KeyCode = Keys.P Then SendKeys.Send("^{PGUP}")
4058             'If e.KeyCode = Keys.F Then
4059             '    e.Handled = True
4060             '    e.SuppressKeyPress = True
4061             '    MovePageScroll(True)
4062             'End If
4063             'If e.KeyCode = Keys.B Then
4064             '    e.Handled = True
4065             '    e.SuppressKeyPress = True
4066             '    MovePageScroll(False)
4067             'End If
4068         End If
4069         If Not e.Control AndAlso e.Alt AndAlso Not e.Shift Then
4070             ' ALTキーが押されている場合
4071             ' 別タブの同じ書き込みへ(ALT+←/→)
4072             If e.KeyCode = Keys.Right Then
4073                 e.Handled = True
4074                 e.SuppressKeyPress = True
4075                 GoSamePostToAnotherTab(False)
4076             End If
4077             If e.KeyCode = Keys.Left Then
4078                 e.Handled = True
4079                 e.SuppressKeyPress = True
4080                 GoSamePostToAnotherTab(True)
4081             End If
4082         End If
4083         If e.Shift AndAlso Not e.Control AndAlso Not e.Alt Then
4084             ' SHIFTキーが押されている場合
4085             If e.KeyCode = Keys.H Then
4086                 e.Handled = True
4087                 e.SuppressKeyPress = True
4088                 GoTopEnd(True)
4089             End If
4090             If e.KeyCode = Keys.L Then
4091                 e.Handled = True
4092                 e.SuppressKeyPress = True
4093                 GoTopEnd(False)
4094             End If
4095             If e.KeyCode = Keys.M Then
4096                 e.Handled = True
4097                 e.SuppressKeyPress = True
4098                 GoMiddle()
4099             End If
4100             If e.KeyCode = Keys.G Then
4101                 e.Handled = True
4102                 e.SuppressKeyPress = True
4103                 GoLast()
4104             End If
4105             If e.KeyCode = Keys.Z Then
4106                 e.Handled = True
4107                 e.SuppressKeyPress = True
4108                 MoveMiddle()
4109             End If
4110
4111             ' お気に入り前後ジャンプ(SHIFT+N←/P→)
4112             If e.KeyCode = Keys.N OrElse e.KeyCode = Keys.Right Then
4113                 e.Handled = True
4114                 e.SuppressKeyPress = True
4115                 GoFav(True)
4116             End If
4117             If e.KeyCode = Keys.P OrElse e.KeyCode = Keys.Left Then
4118                 e.Handled = True
4119                 e.SuppressKeyPress = True
4120                 GoFav(False)
4121             End If
4122             'If e.KeyCode = Keys.B Then
4123             '    e.Handled = True
4124             '    e.SuppressKeyPress = True
4125             '    UnreadStripMenuItem_Click(Nothing, Nothing)
4126             'End If
4127         End If
4128         If Not e.Alt Then
4129             If e.KeyCode = Keys.J Then
4130                 e.Handled = True
4131                 e.SuppressKeyPress = True
4132                 SendKeys.Send("{DOWN}")
4133             End If
4134             If e.KeyCode = Keys.K Then
4135                 e.Handled = True
4136                 e.SuppressKeyPress = True
4137                 SendKeys.Send("{UP}")
4138             End If
4139         End If
4140         If e.KeyCode = Keys.C Then
4141             Dim clstr As String = ""
4142             If e.Control AndAlso Not e.Alt AndAlso Not e.Shift Then
4143                 e.Handled = True
4144                 e.SuppressKeyPress = True
4145                 CopyStot()
4146             End If
4147             If e.Control AndAlso e.Shift AndAlso Not e.Alt Then
4148                 e.Handled = True
4149                 e.SuppressKeyPress = True
4150                 CopyIdUri()
4151             End If
4152         End If
4153     End Sub
4154
4155     Private Sub CopyStot()
4156         Dim clstr As String = ""
4157         Dim sb As New StringBuilder()
4158         For Each idx As Integer In _curList.SelectedIndices
4159             Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
4160             If post.IsProtect AndAlso SettingDialog.ProtectNotInclude Then Continue For
4161             If post.RetweetedId = 0 Then
4162                 sb.AppendFormat("{0}:{1} [http://twitter.com/{0}/status/{2}]{3}", post.Name, post.Data, post.Id, Environment.NewLine)
4163             Else
4164                 sb.AppendFormat("{0}:{1} [http://twitter.com/{2}/status/{3}]{4}", post.Name, post.Data, post.RetweetedBy, post.Id, Environment.NewLine)
4165             End If
4166         Next
4167         If sb.Length > 0 Then
4168             clstr = sb.ToString()
4169             Clipboard.SetDataObject(clstr, False, 5, 100)
4170         End If
4171     End Sub
4172
4173     Private Sub CopyIdUri()
4174         Dim clstr As String = ""
4175         Dim sb As New StringBuilder()
4176         For Each idx As Integer In _curList.SelectedIndices
4177             Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
4178             If String.IsNullOrEmpty(post.RetweetedBy) Then
4179                 sb.AppendFormat("http://twitter.com/{0}/status/{1}{2}", post.Name, post.Id, Environment.NewLine)
4180             Else
4181                 sb.AppendFormat("http://twitter.com/{0}/status/{1}{2}", post.RetweetedBy, post.Id, Environment.NewLine)
4182             End If
4183         Next
4184         If sb.Length > 0 Then
4185             clstr = sb.ToString()
4186             Clipboard.SetDataObject(clstr, False, 5, 100)
4187         End If
4188     End Sub
4189
4190     Private Sub GoFav(ByVal forward As Boolean)
4191         If _curList.VirtualListSize = 0 Then Exit Sub
4192         Dim fIdx As Integer = 0
4193         Dim toIdx As Integer = 0
4194         Dim stp As Integer = 1
4195
4196         If forward Then
4197             If _curList.SelectedIndices.Count = 0 Then
4198                 fIdx = 0
4199             Else
4200                 fIdx = _curList.SelectedIndices(0) + 1
4201                 If fIdx > _curList.VirtualListSize - 1 Then Exit Sub
4202             End If
4203             toIdx = _curList.VirtualListSize - 1
4204             stp = 1
4205         Else
4206             If _curList.SelectedIndices.Count = 0 Then
4207                 fIdx = _curList.VirtualListSize - 1
4208             Else
4209                 fIdx = _curList.SelectedIndices(0) - 1
4210                 If fIdx < 0 Then Exit Sub
4211             End If
4212             toIdx = 0
4213             stp = -1
4214         End If
4215
4216         For idx As Integer = fIdx To toIdx Step stp
4217             If _statuses.Item(_curTab.Text, idx).IsFav Then
4218                 SelectListItem(_curList, idx)
4219                 _curList.EnsureVisible(idx)
4220                 Exit For
4221             End If
4222         Next
4223     End Sub
4224
4225     Private Sub GoSamePostToAnotherTab(ByVal left As Boolean)
4226         If _curList.VirtualListSize = 0 Then Exit Sub
4227         Dim fIdx As Integer = 0
4228         Dim toIdx As Integer = 0
4229         Dim stp As Integer = 1
4230         Dim targetId As Long = 0
4231
4232         If _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage Then Exit Sub ' Directタブは対象外(見つかるはずがない)
4233         If _curList.SelectedIndices.Count = 0 Then Exit Sub '未選択も処理しない
4234
4235         targetId = GetCurTabPost(_curList.SelectedIndices(0)).Id
4236
4237         If left Then
4238             ' 左のタブへ
4239             If ListTab.SelectedIndex = 0 Then
4240                 Exit Sub
4241             Else
4242                 fIdx = ListTab.SelectedIndex - 1
4243             End If
4244             toIdx = 0
4245             stp = -1
4246         Else
4247             ' 右のタブへ
4248             If ListTab.SelectedIndex = ListTab.TabCount - 1 Then
4249                 Exit Sub
4250             Else
4251                 fIdx = ListTab.SelectedIndex + 1
4252             End If
4253             toIdx = ListTab.TabCount - 1
4254             stp = 1
4255         End If
4256
4257         Dim found As Boolean = False
4258         For tabidx As Integer = fIdx To toIdx Step stp
4259             If _statuses.Tabs(ListTab.TabPages(tabidx).Text).TabType = TabUsageType.DirectMessage Then Continue For ' Directタブは対象外
4260             '_itemCache = Nothing
4261             '_postCache = Nothing
4262             For idx As Integer = 0 To DirectCast(ListTab.TabPages(tabidx).Tag, DetailsListView).VirtualListSize - 1
4263                 If _statuses.Item(ListTab.TabPages(tabidx).Text, idx).Id = targetId Then
4264                     ListTab.SelectedIndex = tabidx
4265                     ListTabSelect(ListTab.TabPages(tabidx))
4266                     SelectListItem(_curList, idx)
4267                     _curList.EnsureVisible(idx)
4268                     found = True
4269                     Exit For
4270                 End If
4271             Next
4272             If found Then Exit For
4273         Next
4274         '_itemCache = Nothing
4275         '_postCache = Nothing
4276     End Sub
4277
4278     Private Sub GoPost(ByVal forward As Boolean)
4279         If _curList.SelectedIndices.Count = 0 OrElse _curPost Is Nothing Then Exit Sub
4280         Dim fIdx As Integer = 0
4281         Dim toIdx As Integer = 0
4282         Dim stp As Integer = 1
4283
4284         If forward Then
4285             fIdx = _curList.SelectedIndices(0) + 1
4286             If fIdx > _curList.VirtualListSize - 1 Then Exit Sub
4287             toIdx = _curList.VirtualListSize - 1
4288             stp = 1
4289         Else
4290             fIdx = _curList.SelectedIndices(0) - 1
4291             If fIdx < 0 Then Exit Sub
4292             toIdx = 0
4293             stp = -1
4294         End If
4295
4296         Dim name As String = ""
4297         If _curPost.RetweetedId = 0 Then
4298             name = _curPost.Name
4299         Else
4300             name = _curPost.RetweetedBy
4301         End If
4302         For idx As Integer = fIdx To toIdx Step stp
4303             If _statuses.Item(_curTab.Text, idx).RetweetedId = 0 Then
4304                 If _statuses.Item(_curTab.Text, idx).Name = name Then
4305                     SelectListItem(_curList, idx)
4306                     _curList.EnsureVisible(idx)
4307                     Exit For
4308                 End If
4309             Else
4310                 If _statuses.Item(_curTab.Text, idx).RetweetedBy = name Then
4311                     SelectListItem(_curList, idx)
4312                     _curList.EnsureVisible(idx)
4313                     Exit For
4314                 End If
4315             End If
4316         Next
4317     End Sub
4318
4319     Private Sub GoRelPost(ByVal forward As Boolean)
4320         If _curList.SelectedIndices.Count = 0 Then Exit Sub
4321
4322         Dim fIdx As Integer = 0
4323         Dim toIdx As Integer = 0
4324         Dim stp As Integer = 1
4325         If forward Then
4326             fIdx = _curList.SelectedIndices(0) + 1
4327             If fIdx > _curList.VirtualListSize - 1 Then Exit Sub
4328             toIdx = _curList.VirtualListSize - 1
4329             stp = 1
4330         Else
4331             fIdx = _curList.SelectedIndices(0) - 1
4332             If fIdx < 0 Then Exit Sub
4333             toIdx = 0
4334             stp = -1
4335         End If
4336
4337         If Not _anchorFlag Then
4338             If _curPost Is Nothing Then Exit Sub
4339             _anchorPost = _curPost
4340             _anchorFlag = True
4341         Else
4342             If _anchorPost Is Nothing Then Exit Sub
4343         End If
4344
4345         For idx As Integer = fIdx To toIdx Step stp
4346             Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
4347             If post.Name = _anchorPost.Name OrElse _
4348                post.RetweetedBy = _anchorPost.Name OrElse _
4349                post.Name = _anchorPost.RetweetedBy OrElse _
4350                (Not String.IsNullOrEmpty(post.RetweetedBy) AndAlso post.RetweetedBy = _anchorPost.RetweetedBy) OrElse _
4351                _anchorPost.ReplyToList.Contains(post.Name.ToLower()) OrElse _
4352                _anchorPost.ReplyToList.Contains(post.RetweetedBy.ToLower()) OrElse _
4353                post.ReplyToList.Contains(_anchorPost.Name.ToLower()) OrElse _
4354                post.ReplyToList.Contains(_anchorPost.RetweetedBy.ToLower()) Then
4355                 SelectListItem(_curList, idx)
4356                 _curList.EnsureVisible(idx)
4357                 Exit For
4358             End If
4359         Next
4360     End Sub
4361
4362     Private Sub GoAnchor()
4363         If _anchorPost Is Nothing Then Exit Sub
4364         Dim idx As Integer = _statuses.Tabs(_curTab.Text).IndexOf(_anchorPost.Id)
4365         If idx = -1 Then Exit Sub
4366
4367         SelectListItem(_curList, idx)
4368         _curList.EnsureVisible(idx)
4369     End Sub
4370
4371     Private Sub GoTopEnd(ByVal GoTop As Boolean)
4372         Dim _item As ListViewItem
4373         Dim idx As Integer
4374
4375         If GoTop Then
4376             _item = _curList.GetItemAt(0, 25)
4377             If _item Is Nothing Then
4378                 idx = 0
4379             Else
4380                 idx = _item.Index
4381             End If
4382         Else
4383             _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1)
4384             If _item Is Nothing Then
4385                 idx = _curList.VirtualListSize - 1
4386             Else
4387                 idx = _item.Index
4388             End If
4389         End If
4390         SelectListItem(_curList, idx)
4391     End Sub
4392
4393     Private Sub GoMiddle()
4394         Dim _item As ListViewItem
4395         Dim idx1 As Integer
4396         Dim idx2 As Integer
4397         Dim idx3 As Integer
4398
4399         _item = _curList.GetItemAt(0, 0)
4400         If _item Is Nothing Then
4401             idx1 = 0
4402         Else
4403             idx1 = _item.Index
4404         End If
4405         _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1)
4406         If _item Is Nothing Then
4407             idx2 = _curList.VirtualListSize - 1
4408         Else
4409             idx2 = _item.Index
4410         End If
4411         idx3 = (idx1 + idx2) \ 2
4412
4413         SelectListItem(_curList, idx3)
4414     End Sub
4415
4416     Private Sub GoLast()
4417         If _curList.VirtualListSize = 0 Then Exit Sub
4418
4419         If _statuses.SortOrder = SortOrder.Ascending Then
4420             SelectListItem(_curList, _curList.VirtualListSize - 1)
4421             _curList.EnsureVisible(_curList.VirtualListSize - 1)
4422         Else
4423             SelectListItem(_curList, 0)
4424             _curList.EnsureVisible(0)
4425         End If
4426     End Sub
4427
4428     Private Sub MoveTop()
4429         If _curList.SelectedIndices.Count = 0 Then Exit Sub
4430         Dim idx As Integer = _curList.SelectedIndices(0)
4431         If _statuses.SortOrder = SortOrder.Ascending Then
4432             _curList.EnsureVisible(_curList.VirtualListSize - 1)
4433         Else
4434             _curList.EnsureVisible(0)
4435         End If
4436         _curList.EnsureVisible(idx)
4437     End Sub
4438
4439     'Private Sub MovePageScroll(ByVal down As Boolean)
4440     '    Dim _item As ListViewItem
4441     '    Dim idx As Integer
4442
4443     '    If down Then
4444     '        _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 25)
4445     '        If _item Is Nothing Then
4446     '            If _curList.VirtualListSize > 0 Then
4447     '                SelectListItem(_curList, _curList.VirtualListSize - 1)
4448     '                _curList.EnsureVisible(_curList.VirtualListSize - 1)
4449     '            End If
4450     '            Exit Sub
4451     '        End If
4452
4453     '        idx = _item.Index
4454     '        Dim idx2 As Integer = -1
4455     '        If _curList.Focused Then
4456     '            idx2 = _curList.FocusedItem.Index
4457     '        End If
4458     '        If idx2 >= idx Then
4459     '            'スクロール
4460     '            Dim idx3 As Integer = 0
4461     '            _item = _curList.GetItemAt(0, 25)
4462     '            If _item IsNot Nothing Then
4463     '                idx3 = _item.Index
4464     '            End If
4465     '            Dim rowCount As Integer = idx - idx3
4466     '            Dim toIndex As Integer = 0
4467     '            If idx2 + rowCount > _curList.VirtualListSize - 1 Then
4468     '                toIndex = _curList.VirtualListSize - 1
4469     '            Else
4470     '                toIndex = idx2 + rowCount
4471     '            End If
4472     '            SelectListItem(_curList, toIndex)
4473     '            _curList.EnsureVisible(toIndex)
4474     '        Else
4475     '            '最下行を選択
4476     '            SelectListItem(_curList, idx)
4477     '        End If
4478     '    Else
4479     '        _item = _curList.GetItemAt(0, 25)
4480     '        If _item Is Nothing Then
4481     '            If _curList.VirtualListSize > 0 Then
4482     '                SelectListItem(_curList, 0)
4483     '                _curList.EnsureVisible(0)
4484     '            End If
4485     '            Exit Sub
4486     '        End If
4487
4488     '        idx = _item.Index
4489     '        Dim idx2 As Integer = -1
4490     '        If _curList.Focused Then
4491     '            idx2 = _curList.FocusedItem.Index
4492     '        End If
4493     '        If idx2 <= idx Then
4494     '            'スクロール
4495     '            Dim idx3 As Integer = 0
4496     '            _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 25)
4497     '            If _item IsNot Nothing Then
4498     '                idx3 = _item.Index
4499     '            End If
4500     '            Dim rowCount As Integer = idx3 - idx
4501     '            Dim toIndex As Integer = 0
4502     '            If idx2 - rowCount < 0 Then
4503     '                toIndex = 0
4504     '            Else
4505     '                toIndex = idx2 - rowCount
4506     '            End If
4507     '            SelectListItem(_curList, toIndex)
4508     '            _curList.EnsureVisible(toIndex)
4509     '        Else
4510     '            '最上行を選択
4511     '            SelectListItem(_curList, idx)
4512     '        End If
4513     '    End If
4514
4515     'End Sub
4516
4517     Private Sub MyList_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
4518         _anchorFlag = False
4519     End Sub
4520
4521     Private Sub StatusText_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusText.Enter
4522         ' フォーカスの戻り先を StatusText に設定
4523         Me.Tag = StatusText
4524         StatusText.BackColor = _clInputBackcolor
4525     End Sub
4526
4527     Private Sub StatusText_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusText.Leave
4528         ' フォーカスがメニューに遷移しないならばフォーカスはタブに移ることを期待
4529         If ListTab.SelectedTab IsNot Nothing AndAlso MenuStrip1.Tag Is Nothing Then Me.Tag = ListTab.SelectedTab.Tag
4530         StatusText.BackColor = Color.FromKnownColor(KnownColor.Window)
4531     End Sub
4532
4533     Private Sub StatusText_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles StatusText.KeyDown
4534         If e.Control AndAlso Not e.Alt AndAlso Not e.Shift Then
4535             If e.KeyCode = Keys.A Then
4536                 StatusText.SelectAll()
4537             ElseIf e.KeyCode = Keys.Up OrElse e.KeyCode = Keys.Down Then
4538                 If StatusText.Text.Trim() <> "" Then _history(_hisIdx) = StatusText.Text
4539                 If e.KeyCode = Keys.Up Then
4540                     _hisIdx -= 1
4541                     If _hisIdx < 0 Then _hisIdx = 0
4542                 Else
4543                     _hisIdx += 1
4544                     If _hisIdx > _history.Count - 1 Then _hisIdx = _history.Count - 1
4545                 End If
4546                 StatusText.Text = _history(_hisIdx)
4547                 StatusText.SelectionStart = StatusText.Text.Length
4548                 e.Handled = True
4549                 e.SuppressKeyPress = True
4550             ElseIf e.KeyCode = Keys.PageUp Then
4551                 If ListTab.SelectedIndex = 0 Then
4552                     ListTab.SelectedIndex = ListTab.TabCount - 1
4553                 Else
4554                     ListTab.SelectedIndex -= 1
4555                 End If
4556                 e.Handled = True
4557                 e.SuppressKeyPress = True
4558                 StatusText.Focus()
4559             ElseIf e.KeyCode = Keys.PageDown Then
4560                 If ListTab.SelectedIndex = ListTab.TabCount - 1 Then
4561                     ListTab.SelectedIndex = 0
4562                 Else
4563                     ListTab.SelectedIndex += 1
4564                 End If
4565                 e.Handled = True
4566                 e.SuppressKeyPress = True
4567                 StatusText.Focus()
4568             End If
4569         End If
4570         Me.StatusText_TextChanged(Nothing, Nothing)
4571     End Sub
4572
4573     Private Sub SaveConfigsAll(ByVal ifModified As Boolean)
4574         If Not ifModified Then
4575             SaveConfigsCommon()
4576             SaveConfigsLocal()
4577             'SaveConfigsTab(True)    'True:事前に設定ファイル削除
4578             SaveConfigsTabs()
4579         Else
4580             If modifySettingCommon Then SaveConfigsCommon()
4581             If modifySettingLocal Then SaveConfigsLocal()
4582             If modifySettingAtId AndAlso SettingDialog.UseAtIdSupplement AndAlso AtIdSupl IsNot Nothing Then
4583                 modifySettingAtId = False
4584                 Dim cfgAtId As New SettingAtIdList(AtIdSupl.GetIdList)
4585                 cfgAtId.Save()
4586             End If
4587         End If
4588     End Sub
4589
4590     Private Sub SaveConfigsCommon()
4591         If _ignoreConfigSave Then Exit Sub
4592
4593         If _username <> "" AndAlso _password <> "" Then
4594             modifySettingCommon = False
4595             SyncLock _syncObject
4596                 _cfgCommon.UserName = _username
4597                 _cfgCommon.Password = _password
4598                 _cfgCommon.NextPageThreshold = SettingDialog.NextPageThreshold
4599                 _cfgCommon.NextPages = SettingDialog.NextPagesInt
4600                 _cfgCommon.TimelinePeriod = SettingDialog.TimelinePeriodInt
4601                 _cfgCommon.ReplyPeriod = SettingDialog.ReplyPeriodInt
4602                 _cfgCommon.DMPeriod = SettingDialog.DMPeriodInt
4603                 _cfgCommon.MaxPostNum = SettingDialog.MaxPostNum
4604                 _cfgCommon.ReadPages = SettingDialog.ReadPages
4605                 _cfgCommon.ReadPagesReply = SettingDialog.ReadPagesReply
4606                 _cfgCommon.ReadPagesDM = SettingDialog.ReadPagesDM
4607                 _cfgCommon.Read = SettingDialog.Readed
4608                 _cfgCommon.IconSize = SettingDialog.IconSz
4609                 _cfgCommon.UnreadManage = SettingDialog.UnreadManage
4610                 _cfgCommon.PlaySound = SettingDialog.PlaySound
4611                 _cfgCommon.OneWayLove = SettingDialog.OneWayLove
4612
4613                 _cfgCommon.NameBalloon = SettingDialog.NameBalloon
4614                 _cfgCommon.PostCtrlEnter = SettingDialog.PostCtrlEnter
4615                 _cfgCommon.UseApi = SettingDialog.UseAPI
4616                 _cfgCommon.CountApi = SettingDialog.CountApi
4617                 _cfgCommon.UsePostMethod = False
4618                 _cfgCommon.HubServer = SettingDialog.HubServer
4619                 _cfgCommon.CheckReply = SettingDialog.CheckReply
4620                 _cfgCommon.PostAndGet = SettingDialog.PostAndGet
4621                 _cfgCommon.DispUsername = SettingDialog.DispUsername
4622                 _cfgCommon.MinimizeToTray = SettingDialog.MinimizeToTray
4623                 _cfgCommon.CloseToExit = SettingDialog.CloseToExit
4624                 _cfgCommon.DispLatestPost = SettingDialog.DispLatestPost
4625                 _cfgCommon.SortOrderLock = SettingDialog.SortOrderLock
4626                 _cfgCommon.TinyUrlResolve = SettingDialog.TinyUrlResolve
4627                 _cfgCommon.PeriodAdjust = SettingDialog.PeriodAdjust
4628                 _cfgCommon.StartupVersion = SettingDialog.StartupVersion
4629                 _cfgCommon.StartupKey = SettingDialog.StartupKey
4630                 _cfgCommon.StartupFollowers = SettingDialog.StartupFollowers
4631                 _cfgCommon.StartupApiModeNoWarning = SettingDialog.StartupAPImodeNoWarning
4632                 _cfgCommon.RestrictFavCheck = SettingDialog.RestrictFavCheck
4633                 _cfgCommon.AlwaysTop = SettingDialog.AlwaysTop
4634                 _cfgCommon.UrlConvertAuto = SettingDialog.UrlConvertAuto
4635                 _cfgCommon.Outputz = SettingDialog.OutputzEnabled
4636                 _cfgCommon.OutputzKey = SettingDialog.OutputzKey
4637                 _cfgCommon.OutputzUrlMode = SettingDialog.OutputzUrlmode
4638                 _cfgCommon.UseUnreadStyle = SettingDialog.UseUnreadStyle
4639                 _cfgCommon.DateTimeFormat = SettingDialog.DateTimeFormat
4640                 _cfgCommon.DefaultTimeOut = SettingDialog.DefaultTimeOut
4641                 _cfgCommon.ProtectNotInclude = SettingDialog.ProtectNotInclude
4642                 _cfgCommon.LimitBalloon = SettingDialog.LimitBalloon
4643                 _cfgCommon.AutoShortUrlFirst = SettingDialog.AutoShortUrlFirst
4644                 _cfgCommon.TabIconDisp = SettingDialog.TabIconDisp
4645                 _cfgCommon.ReplyIconState = SettingDialog.ReplyIconState
4646                 _cfgCommon.ReadOwnPost = SettingDialog.ReadOwnPost
4647                 _cfgCommon.GetFav = SettingDialog.GetFav
4648                 _cfgCommon.IsMonospace = SettingDialog.IsMonospace
4649                 If IdeographicSpaceToSpaceToolStripMenuItem IsNot Nothing AndAlso _
4650                    IdeographicSpaceToSpaceToolStripMenuItem.IsDisposed = False Then
4651                     _cfgCommon.WideSpaceConvert = Me.IdeographicSpaceToSpaceToolStripMenuItem.Checked
4652                 End If
4653                 _cfgCommon.ReadOldPosts = SettingDialog.ReadOldPosts
4654                 _cfgCommon.UseSsl = SettingDialog.UseSsl
4655                 _cfgCommon.BilyUser = SettingDialog.BitlyUser
4656                 _cfgCommon.BitlyPwd = SettingDialog.BitlyPwd
4657                 _cfgCommon.ShowGrid = SettingDialog.ShowGrid
4658                 _cfgCommon.UseAtIdSupplement = SettingDialog.UseAtIdSupplement
4659                 _cfgCommon.Language = SettingDialog.Language
4660
4661                 _cfgCommon.SortOrder = _statuses.SortOrder
4662                 Select Case _statuses.SortMode
4663                     Case IdComparerClass.ComparerMode.Nickname  'ニックネーム
4664                         _cfgCommon.SortColumn = 1
4665                     Case IdComparerClass.ComparerMode.Data  '本文
4666                         _cfgCommon.SortColumn = 2
4667                     Case IdComparerClass.ComparerMode.Id  '時刻=発言Id
4668                         _cfgCommon.SortColumn = 3
4669                     Case IdComparerClass.ComparerMode.Name  '名前
4670                         _cfgCommon.SortColumn = 4
4671                     Case IdComparerClass.ComparerMode.Source  'Source
4672                         _cfgCommon.SortColumn = 7
4673                 End Select
4674
4675                 '                _cfgCommon.TabList.Clear()
4676                 '                For i As Integer = 0 To ListTab.TabPages.Count - 1
4677                 '                    Dim tnList As String = ListTab.TabPages(i).Text
4678                 '                    Dim seq As Integer = 1
4679                 'RETRY:
4680                 '                    seq += 1
4681                 '                    For Each tn As String In _cfgCommon.TabList
4682                 '                        If tn.ToLower() = tnList.ToLower() Then
4683                 '                            tnList += "_" + seq.ToString()
4684                 '                        End If
4685                 '                    Next
4686                 '                    _cfgCommon.TabList.Add(ListTab.TabPages(i).Text)
4687                 '                Next
4688
4689                 _cfgCommon.Save()
4690             End SyncLock
4691         End If
4692     End Sub
4693
4694     Private Sub SaveConfigsLocal()
4695         If _ignoreConfigSave Then Exit Sub
4696         SyncLock _syncObject
4697             modifySettingLocal = False
4698             _cfgLocal.FormSize = _mySize
4699             _cfgLocal.FormLocation = _myLoc
4700             _cfgLocal.SplitterDistance = _mySpDis
4701             _cfgLocal.StatusMultiline = StatusText.Multiline
4702             _cfgLocal.StatusTextHeight = _mySpDis2
4703             _cfgLocal.StatusText = SettingDialog.Status
4704
4705             _cfgLocal.FontUnread = _fntUnread
4706             _cfgLocal.ColorUnread = _clUnread
4707             _cfgLocal.FontRead = _fntReaded
4708             _cfgLocal.ColorRead = _clReaded
4709             _cfgLocal.FontDetail = _fntDetail
4710             _cfgLocal.ColorDetail = _clDetail
4711             _cfgLocal.ColorDetailBackcolor = _clDetailBackcolor
4712             _cfgLocal.ColorDetailLink = _clDetailLink
4713             _cfgLocal.ColorFav = _clFav
4714             _cfgLocal.ColorOWL = _clOWL
4715             _cfgLocal.ColorRetweet = _clRetweet
4716             _cfgLocal.ColorSelf = _clSelf
4717             _cfgLocal.ColorAtSelf = _clAtSelf
4718             _cfgLocal.ColorTarget = _clTarget
4719             _cfgLocal.ColorAtTarget = _clAtTarget
4720             _cfgLocal.ColorAtFromTarget = _clAtFromTarget
4721             _cfgLocal.ColorAtTo = _clAtTo
4722             _cfgLocal.ColorListBackcolor = _clListBackcolor
4723             _cfgLocal.ColorInputBackcolor = _clInputBackcolor
4724             _cfgLocal.ColorInputFont = _clInputFont
4725             _cfgLocal.FontInputFont = _fntInputFont
4726
4727             _cfgLocal.BrowserPath = SettingDialog.BrowserPath
4728             _cfgLocal.UseRecommendStatus = SettingDialog.UseRecommendStatus
4729             _cfgLocal.ProxyType = SettingDialog.SelectedProxyType
4730             _cfgLocal.ProxyAddress = SettingDialog.ProxyAddress
4731             _cfgLocal.ProxyPort = SettingDialog.ProxyPort
4732             _cfgLocal.ProxyUser = SettingDialog.ProxyUser
4733             _cfgLocal.ProxyPassword = SettingDialog.ProxyPassword
4734             If _ignoreConfigSave Then Exit Sub
4735             _cfgLocal.Save()
4736         End SyncLock
4737     End Sub
4738
4739     'Private Sub SaveConfigsTab(ByVal DeleteBefore As Boolean)
4740     '    If _ignoreConfigSave Then Exit Sub
4741     '    Dim cnt As Integer = 0
4742     '    If ListTab IsNot Nothing AndAlso _
4743     '       ListTab.TabPages IsNot Nothing AndAlso _
4744     '       ListTab.TabPages.Count > 0 Then
4745     '        If DeleteBefore Then SettingTab.DeleteConfigFile() '旧設定ファイル削除
4746     '        For cnt = 0 To ListTab.TabPages.Count - 1
4747     '            SaveConfigsTab(ListTab.TabPages(cnt).Text)
4748     '        Next
4749     '    End If
4750     'End Sub
4751
4752     'Private Sub SaveConfigsTab(ByVal tabName As String)
4753     '    If _ignoreConfigSave Then Exit Sub
4754     '    SyncLock _syncObject
4755     '        Dim tabSetting As New SettingTab
4756     '        tabSetting.Tab = _statuses.Tabs(tabName)
4757     '        tabSetting.Save()
4758     '    End SyncLock
4759     'End Sub
4760
4761     Private Sub SaveConfigsTabs()
4762         Dim tabSetting As New SettingTabs
4763         For i As Integer = 0 To ListTab.TabPages.Count - 1
4764             tabSetting.Tabs.Add(_statuses.Tabs(ListTab.TabPages(i).Text))
4765         Next
4766         tabSetting.Save()
4767     End Sub
4768
4769     Private Sub SaveLogMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveLogMenuItem.Click
4770         Dim rslt As DialogResult = MessageBox.Show(String.Format(My.Resources.SaveLogMenuItem_ClickText1, Environment.NewLine), _
4771                 My.Resources.SaveLogMenuItem_ClickText2, _
4772                 MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)
4773         If rslt = Windows.Forms.DialogResult.Cancel Then Exit Sub
4774
4775         SaveFileDialog1.FileName = "TweenPosts" + Format(Now, "yyMMdd-HHmmss") + ".tsv"
4776         SaveFileDialog1.InitialDirectory = My.Application.Info.DirectoryPath
4777         SaveFileDialog1.Filter = My.Resources.SaveLogMenuItem_ClickText3
4778         SaveFileDialog1.FilterIndex = 0
4779         SaveFileDialog1.Title = My.Resources.SaveLogMenuItem_ClickText4
4780         SaveFileDialog1.RestoreDirectory = True
4781
4782         If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
4783             If Not SaveFileDialog1.ValidateNames Then Exit Sub
4784             Using sw As StreamWriter = New StreamWriter(SaveFileDialog1.FileName, False, Encoding.UTF8)
4785                 If rslt = Windows.Forms.DialogResult.Yes Then
4786                     'All
4787                     For idx As Integer = 0 To _curList.VirtualListSize - 1
4788                         Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
4789                         sw.WriteLine(post.Nickname & vbTab & _
4790                                  """" & post.Data.Replace(vbLf, "").Replace("""", """""") + """" & vbTab & _
4791                                  post.PDate.ToString() & vbTab & _
4792                                  post.Name & vbTab & _
4793                                  post.Id.ToString() & vbTab & _
4794                                  post.ImageUrl & vbTab & _
4795                                  """" & post.OriginalData.Replace(vbLf, "").Replace("""", """""") + """")
4796                     Next
4797                 Else
4798                     For Each idx As Integer In _curList.SelectedIndices
4799                         Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
4800                         sw.WriteLine(post.Nickname & vbTab & _
4801                                  """" & post.Data.Replace(vbLf, "").Replace("""", """""") + """" & vbTab & _
4802                                  post.PDate.ToString() & vbTab & _
4803                                  post.Name & vbTab & _
4804                                  post.Id.ToString() & vbTab & _
4805                                  post.ImageUrl & vbTab & _
4806                                  """" & post.OriginalData.Replace(vbLf, "").Replace("""", """""") + """")
4807                     Next
4808                 End If
4809                 sw.Close()
4810                 sw.Dispose()
4811             End Using
4812         End If
4813         Me.TopMost = SettingDialog.AlwaysTop
4814     End Sub
4815
4816     Private Sub PostBrowser_PreviewKeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles PostBrowser.PreviewKeyDown
4817         If e.KeyCode = Keys.F5 OrElse e.KeyCode = Keys.R Then
4818             e.IsInputKey = True
4819             DoRefresh()
4820         End If
4821         If e.Modifiers = Keys.None AndAlso (e.KeyCode = Keys.Space OrElse e.KeyCode = Keys.ProcessKey) Then
4822             e.IsInputKey = True
4823             JumpUnreadMenuItem_Click(Nothing, Nothing)
4824         End If
4825     End Sub
4826
4827     Public Function TabRename(ByRef tabName As String) As Boolean
4828         'タブ名変更
4829         'If _statuses.IsDefaultTab(tabName) Then Return False
4830         Dim newTabText As String = Nothing
4831         Using inputName As New InputTabName()
4832             inputName.TabName = tabName
4833             inputName.ShowDialog()
4834             newTabText = inputName.TabName
4835             inputName.Dispose()
4836         End Using
4837         Me.TopMost = SettingDialog.AlwaysTop
4838         If newTabText <> "" Then
4839             '新タブ名存在チェック
4840             For i As Integer = 0 To ListTab.TabCount - 1
4841                 If ListTab.TabPages(i).Text = newTabText OrElse _
4842                    newTabText <> ReplaceInvalidFilename(newTabText) Then
4843                     Dim tmp As String = String.Format(My.Resources.Tabs_DoubleClickText1, newTabText)
4844                     MessageBox.Show(tmp, My.Resources.Tabs_DoubleClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
4845                     Return False
4846                 End If
4847             Next
4848             'タブ名のリスト作り直し(デフォルトタブ以外は再作成)
4849             For i As Integer = 0 To ListTab.TabCount - 1
4850                 If _statuses.Tabs(ListTab.TabPages(i).Text).TabType = TabUsageType.Mentions OrElse Not _statuses.IsDefaultTab(ListTab.TabPages(i).Text) Then
4851                     TabDialog.RemoveTab(ListTab.TabPages(i).Text)
4852                 End If
4853                 If ListTab.TabPages(i).Text = tabName Then
4854                     ListTab.TabPages(i).Text = newTabText
4855                 End If
4856             Next
4857             _statuses.RenameTab(tabName, newTabText)
4858
4859             For i As Integer = 0 To ListTab.TabCount - 1
4860                 If _statuses.Tabs(ListTab.TabPages(i).Text).TabType = TabUsageType.Mentions OrElse Not _statuses.IsDefaultTab(ListTab.TabPages(i).Text) Then
4861                     If ListTab.TabPages(i).Text = tabName Then
4862                         ListTab.TabPages(i).Text = newTabText
4863                     End If
4864                     TabDialog.AddTab(ListTab.TabPages(i).Text)
4865                 End If
4866             Next
4867             SaveConfigsCommon()
4868             'SaveConfigsTab(newTabText)
4869             SaveConfigsTabs()
4870             _rclickTabName = newTabText
4871             tabName = newTabText
4872             Return True
4873         End If
4874     End Function
4875
4876     Private Sub Tabs_DoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseDoubleClick
4877         Dim tn As String = ListTab.SelectedTab.Text
4878         TabRename(tn)
4879     End Sub
4880
4881     Private Sub Tabs_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseDown
4882         Dim cpos As New Point(e.X, e.Y)
4883         If e.Button = Windows.Forms.MouseButtons.Left Then
4884             For i As Integer = 0 To ListTab.TabPages.Count - 1
4885                 Dim rect As Rectangle = ListTab.GetTabRect(i)
4886                 If rect.Left <= cpos.X AndAlso cpos.X <= rect.Right AndAlso _
4887                    rect.Top <= cpos.Y AndAlso cpos.Y <= rect.Bottom Then
4888                     _tabDrag = True
4889                     Exit For
4890                 End If
4891             Next
4892         Else
4893             _tabDrag = False
4894         End If
4895     End Sub
4896
4897     Private Sub Tabs_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListTab.DragEnter
4898         If e.Data.GetDataPresent(GetType(TabPage)) Then
4899             e.Effect = DragDropEffects.Move
4900         Else
4901             e.Effect = DragDropEffects.None
4902         End If
4903     End Sub
4904
4905     Private Sub Tabs_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListTab.DragDrop
4906         If Not e.Data.GetDataPresent(GetType(TabPage)) Then Exit Sub
4907
4908         _tabDrag = False
4909         Dim tn As String = ""
4910         Dim bef As Boolean
4911         Dim cpos As New Point(e.X, e.Y)
4912         Dim spos As Point = ListTab.PointToClient(cpos)
4913         Dim i As Integer
4914         For i = 0 To ListTab.TabPages.Count - 1
4915             Dim rect As Rectangle = ListTab.GetTabRect(i)
4916             If rect.Left <= spos.X AndAlso spos.X <= rect.Right AndAlso _
4917                rect.Top <= spos.Y AndAlso spos.Y <= rect.Bottom Then
4918                 tn = ListTab.TabPages(i).Text
4919                 If spos.X <= (rect.Left + rect.Right) / 2 Then
4920                     bef = True
4921                 Else
4922                     bef = False
4923                 End If
4924                 Exit For
4925             End If
4926         Next
4927
4928         'タブのないところにドロップ->最後尾へ移動
4929         If tn = "" Then
4930             tn = ListTab.TabPages(ListTab.TabPages.Count - 1).Text
4931             bef = False
4932             i = ListTab.TabPages.Count - 1
4933         End If
4934
4935         Dim tp As TabPage = DirectCast(e.Data.GetData(GetType(TabPage)), TabPage)
4936         If tp.Text = tn Then Exit Sub
4937
4938         ReOrderTab(tp.Text, tn, bef)
4939     End Sub
4940
4941     Public Sub ReOrderTab(ByVal targetTabText As String, ByVal baseTabText As String, ByVal isBeforeBaseTab As Boolean)
4942         Dim baseIndex As Integer = 0
4943         For baseIndex = 0 To ListTab.TabPages.Count - 1
4944             If ListTab.TabPages(baseIndex).Text = baseTabText Then Exit For
4945         Next
4946
4947         ListTab.SuspendLayout()
4948
4949         Dim mTp As TabPage = Nothing
4950         For j As Integer = 0 To ListTab.TabPages.Count - 1
4951             If ListTab.TabPages(j).Text = targetTabText Then
4952                 mTp = ListTab.TabPages(j)
4953                 ListTab.TabPages.Remove(mTp)
4954                 If j < baseIndex Then baseIndex -= 1
4955                 Exit For
4956             End If
4957         Next
4958         If isBeforeBaseTab Then
4959             ListTab.TabPages.Insert(baseIndex, mTp)
4960         Else
4961             ListTab.TabPages.Insert(baseIndex + 1, mTp)
4962         End If
4963
4964         ListTab.ResumeLayout()
4965
4966         SaveConfigsTabs()
4967     End Sub
4968
4969     Private Sub MakeReplyOrDirectStatus(Optional ByVal isAuto As Boolean = True, Optional ByVal isReply As Boolean = True, Optional ByVal isAll As Boolean = False)
4970         'isAuto:True=先頭に挿入、False=カーソル位置に挿入
4971         'isReply:True=@,False=DM
4972         If Not StatusText.Enabled Then Exit Sub
4973         If _curList Is Nothing Then Exit Sub
4974         If _curTab Is Nothing Then Exit Sub
4975         If _curPost Is Nothing Then Exit Sub
4976
4977         ' 複数あてリプライはReplyではなく通常ポスト
4978         '↑仕様変更で全部リプライ扱いでOK(先頭ドット付加しない)
4979         '090403暫定でドットを付加しないようにだけ修正。単独と複数の処理は統合できると思われる。
4980         '090513 all @ replies 廃止の仕様変更によりドット付加に戻し(syo68k)
4981
4982         If _curList.SelectedIndices.Count > 0 Then
4983             ' アイテムが1件以上選択されている
4984             If _curList.SelectedIndices.Count = 1 AndAlso Not isAll AndAlso _curPost IsNot Nothing Then
4985                 ' 単独ユーザー宛リプライまたはDM
4986                 If (_statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.DirectMessage AndAlso isAuto) OrElse (Not isAuto AndAlso Not isReply) Then
4987                     ' ダイレクトメッセージ
4988                     StatusText.Text = "D " + _curPost.Name + " " + StatusText.Text
4989                     StatusText.SelectionStart = StatusText.Text.Length
4990                     StatusText.Focus()
4991                     _reply_to_id = 0
4992                     _reply_to_name = ""
4993                     Exit Sub
4994                 End If
4995                 If StatusText.Text = "" Then
4996                     '空の場合
4997
4998                     ' ステータステキストが入力されていない場合先頭に@ユーザー名を追加する
4999                     StatusText.Text = "@" + _curPost.Name + " "
5000                     If _curPost.RetweetedId > 0 Then
5001                         _reply_to_id = _curPost.RetweetedId
5002                     Else
5003                         _reply_to_id = _curPost.Id
5004                     End If
5005                     _reply_to_name = _curPost.Name
5006                 Else
5007                     '何か入力済の場合
5008
5009                     If isAuto Then
5010                         '1件選んでEnter or DoubleClick
5011                         If StatusText.Text.Contains("@" + _curPost.Name + " ") Then
5012                             If _reply_to_id > 0 AndAlso _reply_to_name = _curPost.Name Then
5013                                 '返信先書き換え
5014                                 If _curPost.RetweetedId > 0 Then
5015                                     _reply_to_id = _curPost.RetweetedId
5016                                 Else
5017                                     _reply_to_id = _curPost.Id
5018                                 End If
5019                                 _reply_to_name = _curPost.Name
5020                             End If
5021                             Exit Sub
5022                         End If
5023                         If Not StatusText.Text.StartsWith("@") Then
5024                             '文頭@以外
5025                             If StatusText.Text.StartsWith(". ") Then
5026                                 ' 複数リプライ
5027                                 StatusText.Text = StatusText.Text.Insert(2, "@" + _curPost.Name + " ")
5028                                 _reply_to_id = 0
5029                                 _reply_to_name = ""
5030                             Else
5031                                 ' 単独リプライ
5032                                 StatusText.Text = "@" + _curPost.Name + " " + StatusText.Text
5033                                 If _curPost.RetweetedId > 0 Then
5034                                     _reply_to_id = _curPost.RetweetedId
5035                                 Else
5036                                     _reply_to_id = _curPost.Id
5037                                 End If
5038                                 _reply_to_name = _curPost.Name
5039                             End If
5040                         Else
5041                             '文頭@
5042                             ' 複数リプライ
5043                             StatusText.Text = ". @" + _curPost.Name + " " + StatusText.Text
5044                             'StatusText.Text = "@" + _curPost.Name + " " + StatusText.Text
5045                             _reply_to_id = 0
5046                             _reply_to_name = ""
5047                         End If
5048                     Else
5049                         '1件選んでCtrl-Rの場合(返信先操作せず)
5050                         Dim sidx As Integer = StatusText.SelectionStart
5051                         Dim id As String = "@" + _curPost.Name + " "
5052                         If sidx > 0 Then
5053                             If StatusText.Text.Substring(sidx - 1, 1) <> " " Then
5054                                 id = " " + id
5055                             End If
5056                         End If
5057                         StatusText.Text = StatusText.Text.Insert(sidx, id)
5058                         sidx += id.Length
5059                         'If StatusText.Text.StartsWith("@") Then
5060                         '    '複数リプライ
5061                         '    StatusText.Text = ". " + StatusText.Text.Insert(sidx, " @" + _curPost.Name + " ")
5062                         '    sidx += 5 + _curPost.Name.Length
5063                         'Else
5064                         '    ' 複数リプライ
5065                         '    StatusText.Text = StatusText.Text.Insert(sidx, " @" + _curPost.Name + " ")
5066                         '    sidx += 3 + _curPost.Name.Length
5067                         'End If
5068                         StatusText.SelectionStart = sidx
5069                         StatusText.Focus()
5070                         '_reply_to_id = 0
5071                         '_reply_to_name = Nothing
5072                         Exit Sub
5073                     End If
5074                 End If
5075             Else
5076                 ' 複数リプライ
5077                 If Not isAuto AndAlso Not isReply Then Exit Sub
5078
5079                 'C-S-rか、複数の宛先を選択中にEnter/DoubleClick/C-r/C-S-r
5080
5081                 If isAuto Then
5082                     'Enter or DoubleClick
5083
5084                     Dim sTxt As String = StatusText.Text
5085                     If Not sTxt.StartsWith(". ") Then
5086                         sTxt = ". " + sTxt
5087                         _reply_to_id = 0
5088                         _reply_to_name = ""
5089                     End If
5090                     For cnt As Integer = 0 To _curList.SelectedIndices.Count - 1
5091                         Dim post As PostClass = _statuses.Item(_curTab.Text, _curList.SelectedIndices(cnt))
5092                         If Not sTxt.Contains("@" + post.Name + " ") Then
5093                             sTxt = sTxt.Insert(2, "@" + post.Name + " ")
5094                             'sTxt = "@" + post.Name + " " + sTxt
5095                         End If
5096                     Next
5097                     StatusText.Text = sTxt
5098                 Else
5099                     'C-S-r or C-r
5100                     If _curList.SelectedIndices.Count > 1 Then
5101                         '複数ポスト選択
5102
5103                         Dim ids As String = ""
5104                         Dim sidx As Integer = StatusText.SelectionStart
5105                         For cnt As Integer = 0 To _curList.SelectedIndices.Count - 1
5106                             Dim post As PostClass = _statuses.Item(_curTab.Text, _curList.SelectedIndices(cnt))
5107                             If Not ids.Contains("@" + post.Name + " ") AndAlso _
5108                                Not post.Name.Equals(_username, StringComparison.CurrentCultureIgnoreCase) Then
5109                                 ids += "@" + post.Name + " "
5110                             End If
5111                             If isAll Then
5112                                 For Each nm As String In post.ReplyToList
5113                                     If Not ids.Contains("@" + nm + " ") AndAlso _
5114                                        Not nm.Equals(_username, StringComparison.CurrentCultureIgnoreCase) Then
5115                                         ids += "@" + nm + " "
5116                                     End If
5117                                 Next
5118                             End If
5119                         Next
5120                         If ids.Length = 0 Then Exit Sub
5121                         If Not StatusText.Text.StartsWith(". ") Then
5122                             StatusText.Text = ". " + StatusText.Text
5123                             sidx += 2
5124                             _reply_to_id = 0
5125                             _reply_to_name = ""
5126                         End If
5127                         If sidx > 0 Then
5128                             If StatusText.Text.Substring(sidx - 1, 1) <> " " Then
5129                                 ids = " " + ids
5130                             End If
5131                         End If
5132                         StatusText.Text = StatusText.Text.Insert(sidx, ids)
5133                         sidx += ids.Length
5134                         'If StatusText.Text.StartsWith("@") Then
5135                         '    StatusText.Text = ". " + StatusText.Text.Insert(sidx, ids)
5136                         '    sidx += 2 + ids.Length
5137                         'Else
5138                         '    StatusText.Text = StatusText.Text.Insert(sidx, ids)
5139                         '    sidx += 1 + ids.Length
5140                         'End If
5141                         StatusText.SelectionStart = sidx
5142                         StatusText.Focus()
5143                         Exit Sub
5144                     Else
5145                         '1件のみ選択のC-S-r(返信元付加する可能性あり)
5146
5147                         Dim ids As String = ""
5148                         Dim sidx As Integer = StatusText.SelectionStart
5149                         Dim post As PostClass = _curPost
5150                         If Not ids.Contains("@" + post.Name + " ") AndAlso _
5151                            Not post.Name.Equals(_username, StringComparison.CurrentCultureIgnoreCase) Then
5152                             ids += "@" + post.Name + " "
5153                         End If
5154                         For Each nm As String In post.ReplyToList
5155                             If Not ids.Contains("@" + nm + " ") AndAlso _
5156                                Not nm.Equals(_username, StringComparison.CurrentCultureIgnoreCase) Then
5157                                 ids += "@" + nm + " "
5158                             End If
5159                         Next
5160                         If ids.Length = 0 Then Exit Sub
5161                         If StatusText.Text = "" Then
5162                             '未入力の場合のみ返信先付加
5163                             StatusText.Text = ids
5164                             StatusText.SelectionStart = ids.Length
5165                             StatusText.Focus()
5166                             If post.RetweetedId > 0 Then
5167                                 _reply_to_id = post.RetweetedId
5168                             Else
5169                                 _reply_to_id = post.Id
5170                             End If
5171                             _reply_to_name = post.Name
5172                             Exit Sub
5173                         End If
5174
5175                         If sidx > 0 Then
5176                             If StatusText.Text.Substring(sidx - 1, 1) <> " " Then
5177                                 ids = " " + ids
5178                             End If
5179                         End If
5180                         StatusText.Text = StatusText.Text.Insert(sidx, ids)
5181                         sidx += ids.Length
5182                         StatusText.SelectionStart = sidx
5183                         StatusText.Focus()
5184                         Exit Sub
5185                     End If
5186                 End If
5187             End If
5188             StatusText.SelectionStart = StatusText.Text.Length
5189             StatusText.Focus()
5190         End If
5191     End Sub
5192
5193     Private Sub ListTab_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseUp
5194         _tabDrag = False
5195     End Sub
5196
5197     Private Sub TimerRefreshIcon_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerRefreshIcon.Tick
5198         If Not TimerRefreshIcon.Enabled Then Exit Sub
5199         Static iconCnt As Integer = 0
5200         Static blinkCnt As Integer = 0
5201         Static blink As Boolean = False
5202         Static idle As Boolean = False
5203
5204         iconCnt += 1
5205         blinkCnt += 1
5206
5207         Dim busy As Boolean = False
5208         For Each bw As BackgroundWorker In Me._bw
5209             If bw IsNot Nothing AndAlso bw.IsBusy Then
5210                 busy = True
5211                 Exit For
5212             End If
5213         Next
5214
5215         If iconCnt > 3 Then
5216             iconCnt = 0
5217         End If
5218         If blinkCnt > 10 Then
5219             blinkCnt = 0
5220             '未保存の変更を保存
5221             SaveConfigsAll(True)
5222         End If
5223
5224         If busy Then
5225             NotifyIcon1.Icon = NIconRefresh(iconCnt)
5226             idle = False
5227             _myStatusError = False
5228             Exit Sub
5229         End If
5230
5231         If SettingDialog.ReplyIconState <> REPLY_ICONSTATE.None AndAlso _statuses.GetTabByType(TabUsageType.Mentions).UnreadCount > 0 Then
5232             If blinkCnt > 0 Then Exit Sub
5233             blink = Not blink
5234             If blink OrElse SettingDialog.ReplyIconState = REPLY_ICONSTATE.StaticIcon Then
5235                 NotifyIcon1.Icon = ReplyIcon
5236             Else
5237                 NotifyIcon1.Icon = ReplyIconBlink
5238             End If
5239             idle = False
5240             Exit Sub
5241         End If
5242
5243         If idle Then Exit Sub
5244         idle = True
5245         '優先度:エラー→オフライン→アイドル
5246         'エラーは更新アイコンでクリアされる
5247         If _myStatusError Then
5248             NotifyIcon1.Icon = NIconAtRed
5249             Exit Sub
5250         End If
5251         If _myStatusOnline Then
5252             NotifyIcon1.Icon = NIconAt
5253         Else
5254             NotifyIcon1.Icon = NIconAtSmoke
5255         End If
5256     End Sub
5257
5258     Private Sub ContextMenuTabProperty_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuTabProperty.Opening
5259         '右クリックの場合はタブ名が設定済。アプリケーションキーの場合は現在のタブを対象とする
5260         If _rclickTabName = "" OrElse ContextMenuTabProperty.OwnerItem IsNot Nothing Then _rclickTabName = ListTab.SelectedTab.Text
5261         If _statuses Is Nothing Then Exit Sub
5262         If _statuses.Tabs Is Nothing Then Exit Sub
5263
5264         Dim tb As TabClass = _statuses.Tabs(_rclickTabName)
5265         If tb Is Nothing Then Exit Sub
5266
5267         NotifyDispMenuItem.Checked = tb.Notify
5268
5269         soundfileListup = True
5270         SoundFileComboBox.Items.Clear()
5271         SoundFileComboBox.Items.Add("")
5272         Dim oDir As IO.DirectoryInfo = New IO.DirectoryInfo(My.Application.Info.DirectoryPath)
5273         For Each oFile As IO.FileInfo In oDir.GetFiles("*.wav")
5274             SoundFileComboBox.Items.Add(oFile.Name)
5275         Next
5276         Dim idx As Integer = SoundFileComboBox.Items.IndexOf(tb.SoundFile)
5277         If idx = -1 Then idx = 0
5278         SoundFileComboBox.SelectedIndex = idx
5279         soundfileListup = False
5280         UreadManageMenuItem.Checked = tb.UnreadManage
5281         If _statuses.Tabs(_rclickTabName).TabType <> TabUsageType.Mentions AndAlso _statuses.IsDefaultTab(_rclickTabName) Then
5282             FilterEditMenuItem.Enabled = True
5283             DeleteTabMenuItem.Enabled = False
5284         ElseIf _statuses.Tabs(_rclickTabName).TabType = TabUsageType.Mentions Then
5285             FilterEditMenuItem.Enabled = True
5286             DeleteTabMenuItem.Enabled = False
5287         Else
5288             FilterEditMenuItem.Enabled = True
5289             DeleteTabMenuItem.Enabled = True
5290         End If
5291     End Sub
5292
5293     Private Sub UreadManageMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UreadManageMenuItem.Click
5294         If _rclickTabName = "" Then Exit Sub
5295
5296         ChangeTabUnreadManage(_rclickTabName, UreadManageMenuItem.Checked)
5297
5298         'SaveConfigsTab(_rclickTabName)
5299         SaveConfigsTabs()
5300     End Sub
5301
5302     Public Sub ChangeTabUnreadManage(ByVal tabName As String, ByVal isManage As Boolean)
5303
5304         Dim idx As Integer
5305         For idx = 0 To ListTab.TabCount
5306             If ListTab.TabPages(idx).Text = tabName Then Exit For
5307         Next
5308
5309         _statuses.SetTabUnreadManage(tabName, isManage)
5310         If SettingDialog.TabIconDisp Then
5311             If _statuses.Tabs(tabName).UnreadCount > 0 Then
5312                 ListTab.TabPages(idx).ImageIndex = 0
5313             Else
5314                 ListTab.TabPages(idx).ImageIndex = -1
5315             End If
5316         End If
5317
5318         If _curTab.Text = tabName Then
5319             _itemCache = Nothing
5320             _postCache = Nothing
5321             _curList.Refresh()
5322         End If
5323
5324         SetMainWindowTitle()
5325         SetStatusLabel()
5326         If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
5327     End Sub
5328
5329     Private Sub NotifyDispMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NotifyDispMenuItem.Click
5330         If _rclickTabName = "" Then Exit Sub
5331
5332         _statuses.Tabs(_rclickTabName).Notify = NotifyDispMenuItem.Checked
5333
5334         'SaveConfigsTab(_rclickTabName)
5335         SaveConfigsTabs()
5336     End Sub
5337
5338     Private Sub SoundFileComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SoundFileComboBox.SelectedIndexChanged
5339         If soundfileListup OrElse _rclickTabName = "" Then Exit Sub
5340
5341         _statuses.Tabs(_rclickTabName).SoundFile = DirectCast(SoundFileComboBox.SelectedItem, String)
5342
5343         'SaveConfigsTab(_rclickTabName)
5344         SaveConfigsTabs()
5345     End Sub
5346
5347     Private Sub DeleteTabMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DeleteTabMenuItem.Click
5348         If _rclickTabName = "" Then Exit Sub
5349
5350         RemoveSpecifiedTab(_rclickTabName)
5351         _rclickTabName = ""
5352         SaveConfigsCommon()
5353         'SaveConfigsTab(False)
5354         SaveConfigsTabs()
5355     End Sub
5356
5357     Private Sub FilterEditMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FilterEditMenuItem.Click
5358         'If _rclickTabName = "" OrElse _rclickTabName = DEFAULTTAB.RECENT OrElse _rclickTabName = DEFAULTTAB.DM _
5359         '        OrElse _rclickTabName = DEFAULTTAB.FAV Then Exit Sub
5360
5361         If _rclickTabName = "" Then _rclickTabName = _statuses.GetTabByType(TabUsageType.Home).TabName
5362         fDialog.SetCurrent(_rclickTabName)
5363         fDialog.ShowDialog()
5364         Me.TopMost = SettingDialog.AlwaysTop
5365
5366         Try
5367             Me.Cursor = Cursors.WaitCursor
5368             _itemCache = Nothing
5369             _postCache = Nothing
5370             _curPost = Nothing
5371             _curItemIndex = -1
5372             _statuses.FilterAll()
5373             For Each tb As TabPage In ListTab.TabPages
5374                 DirectCast(tb.Tag, DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
5375                 If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
5376                     If SettingDialog.TabIconDisp Then
5377                         tb.ImageIndex = 0
5378                     End If
5379                 Else
5380                     If SettingDialog.TabIconDisp Then
5381                         tb.ImageIndex = -1
5382                     End If
5383                 End If
5384             Next
5385             If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
5386         Finally
5387             Me.Cursor = Cursors.Default
5388         End Try
5389         'SaveConfigsTab(False)
5390         SaveConfigsTabs()
5391     End Sub
5392
5393     Private Sub AddTabMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddTabMenuItem.Click
5394         Dim tabName As String = Nothing
5395         Using inputName As New InputTabName()
5396             inputName.TabName = "MyTab" + (ListTab.TabPages.Count + 1).ToString
5397             inputName.ShowDialog()
5398             tabName = inputName.TabName
5399             inputName.Dispose()
5400         End Using
5401         Me.TopMost = SettingDialog.AlwaysTop
5402         If tabName <> "" Then
5403             If Not AddNewTab(tabName, False, TabUsageType.UserDefined) Then
5404                 Dim tmp As String = String.Format(My.Resources.AddTabMenuItem_ClickText1, tabName)
5405                 MessageBox.Show(tmp, My.Resources.AddTabMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
5406             Else
5407                 '成功
5408                 _statuses.AddTab(tabName, TabUsageType.UserDefined)
5409                 SaveConfigsCommon()
5410                 'SaveConfigsTab(False)
5411                 SaveConfigsTabs()
5412             End If
5413         End If
5414     End Sub
5415
5416     Private Sub TabMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TabMenuItem.Click
5417         '選択発言を元にフィルタ追加
5418         For Each idx As Integer In _curList.SelectedIndices
5419             Dim tabName As String = ""
5420             Do
5421                 '振り分け先タブ選択
5422                 If TabDialog.ShowDialog = Windows.Forms.DialogResult.Cancel Then
5423                     Me.TopMost = SettingDialog.AlwaysTop
5424                     Exit For
5425                 End If
5426                 Me.TopMost = SettingDialog.AlwaysTop
5427                 tabName = TabDialog.SelectedTabName
5428
5429                 ListTab.SelectedTab.Focus()
5430                 '新規タブが選択→タブ追加
5431                 If tabName = My.Resources.TabMenuItem_ClickText1 Then
5432                     Using inputName As New InputTabName()
5433                         inputName.TabName = "MyTab" + ListTab.TabPages.Count.ToString
5434                         inputName.ShowDialog()
5435                         tabName = inputName.TabName
5436                         inputName.Dispose()
5437                     End Using
5438                     Me.TopMost = SettingDialog.AlwaysTop
5439                     If tabName.Length > 0 Then
5440                         If Not AddNewTab(tabName, False, TabUsageType.UserDefined) Then
5441                             Dim tmp As String = String.Format(My.Resources.TabMenuItem_ClickText2, tabName)
5442                             MessageBox.Show(tmp, My.Resources.TabMenuItem_ClickText3, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
5443                         Else
5444                             _statuses.AddTab(tabName, TabUsageType.UserDefined)
5445                             Exit Do
5446                         End If
5447                     End If
5448                 Else
5449                     Exit Do
5450                 End If
5451             Loop While True
5452             fDialog.SetCurrent(tabName)
5453             If _statuses.Item(_curTab.Text, idx).RetweetedId = 0 Then
5454                 fDialog.AddNewFilter(_statuses.Item(_curTab.Text, idx).Name, _statuses.Item(_curTab.Text, idx).Data)
5455             Else
5456                 fDialog.AddNewFilter(_statuses.Item(_curTab.Text, idx).RetweetedBy, _statuses.Item(_curTab.Text, idx).Data)
5457             End If
5458             fDialog.ShowDialog()
5459             Me.TopMost = SettingDialog.AlwaysTop
5460         Next
5461
5462         Try
5463             Me.Cursor = Cursors.WaitCursor
5464             _itemCache = Nothing
5465             _postCache = Nothing
5466             _curPost = Nothing
5467             _curItemIndex = -1
5468             _statuses.FilterAll()
5469             For Each tb As TabPage In ListTab.TabPages
5470                 DirectCast(tb.Tag, DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
5471                 If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
5472                     If SettingDialog.TabIconDisp Then
5473                         tb.ImageIndex = 0
5474                     End If
5475                 Else
5476                     If SettingDialog.TabIconDisp Then
5477                         tb.ImageIndex = -1
5478                     End If
5479                 End If
5480             Next
5481             If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
5482         Finally
5483             Me.Cursor = Cursors.Default
5484         End Try
5485         SaveConfigsCommon()
5486         'SaveConfigsTab(False)
5487         SaveConfigsTabs()
5488     End Sub
5489
5490     Protected Overrides Function ProcessDialogKey( _
5491         ByVal keyData As Keys) As Boolean
5492         'TextBox1でEnterを押してもビープ音が鳴らないようにする
5493         If StatusText.Focused AndAlso _
5494             (keyData And Keys.KeyCode) = Keys.Enter Then
5495             '改行
5496             If StatusText.Multiline AndAlso _
5497                (keyData And Keys.Shift) = Keys.Shift AndAlso _
5498                (keyData And Keys.Control) <> Keys.Control Then
5499                 Dim pos1 As Integer = StatusText.SelectionStart
5500                 If StatusText.SelectionLength > 0 Then
5501                     StatusText.Text = StatusText.Text.Remove(pos1, StatusText.SelectionLength)  '選択状態文字列削除
5502                 End If
5503                 StatusText.Text = StatusText.Text.Insert(pos1, Environment.NewLine)  '改行挿入
5504                 StatusText.SelectionStart = pos1 + Environment.NewLine.Length    'カーソルを改行の次の文字へ移動
5505                 Return True
5506             End If
5507             '投稿
5508             If (Not StatusText.Multiline AndAlso _
5509                     ((keyData And Keys.Control) = Keys.Control AndAlso SettingDialog.PostCtrlEnter) OrElse _
5510                     ((keyData And Keys.Control) <> Keys.Control AndAlso Not SettingDialog.PostCtrlEnter)) OrElse _
5511                (StatusText.Multiline AndAlso _
5512                     (Not SettingDialog.PostCtrlEnter AndAlso _
5513                         ((keyData And Keys.Control) <> Keys.Control AndAlso (keyData And Keys.Shift) <> Keys.Shift) OrElse _
5514                         ((keyData And Keys.Control) = Keys.Control AndAlso (keyData And Keys.Shift) = Keys.Shift)) OrElse _
5515                     (SettingDialog.PostCtrlEnter AndAlso (keyData And Keys.Control) = Keys.Control)) Then
5516                 PostButton_Click(Nothing, Nothing)
5517                 Return True
5518             End If
5519         End If
5520         Return MyBase.ProcessDialogKey(keyData)
5521     End Function
5522
5523     Private Sub InfoTwitterMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles InfoTwitterMenuItem.Click
5524         If Twitter.InfoTwitter.Trim() = "" Then
5525             MessageBox.Show(My.Resources.InfoTwitterMenuItem_ClickText1, My.Resources.InfoTwitterMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Information)
5526         Else
5527             Dim inf As String = Twitter.InfoTwitter.Trim()
5528             inf = "<html><head></head><body>" + inf + "</body></html>"
5529             PostBrowser.Visible = False
5530             PostBrowser.DocumentText = inf
5531             PostBrowser.Visible = True
5532         End If
5533     End Sub
5534
5535     Private Sub ReplyAllStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReplyAllStripMenuItem.Click
5536         MakeReplyOrDirectStatus(False, True, True)
5537     End Sub
5538
5539     Private Sub IDRuleMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IDRuleMenuItem.Click
5540         Dim tabName As String = ""
5541
5542         '未選択なら処理終了
5543         If _curList.SelectedIndices.Count = 0 Then Exit Sub
5544
5545         Do
5546             '振り分け先タブ選択
5547             If TabDialog.ShowDialog = Windows.Forms.DialogResult.Cancel Then
5548                 Me.TopMost = SettingDialog.AlwaysTop
5549                 Exit Sub
5550             End If
5551             Me.TopMost = SettingDialog.AlwaysTop
5552             tabName = TabDialog.SelectedTabName
5553
5554             ListTab.SelectedTab.Focus()
5555             '新規タブを選択→タブ作成
5556             If tabName = My.Resources.IDRuleMenuItem_ClickText1 Then
5557                 Using inputName As New InputTabName()
5558                     inputName.TabName = "MyTab" + ListTab.TabPages.Count.ToString
5559                     inputName.ShowDialog()
5560                     tabName = inputName.TabName
5561                     inputName.Dispose()
5562                 End Using
5563                 Me.TopMost = SettingDialog.AlwaysTop
5564                 If tabName <> "" Then
5565                     If Not AddNewTab(tabName, False, TabUsageType.UserDefined) Then
5566                         Dim tmp As String = String.Format(My.Resources.IDRuleMenuItem_ClickText2, tabName)
5567                         MessageBox.Show(tmp, My.Resources.IDRuleMenuItem_ClickText3, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
5568                     Else
5569                         _statuses.AddTab(tabName, TabUsageType.UserDefined)
5570                         Exit Do
5571                     End If
5572                 End If
5573             Else
5574                 '既存タブを選択
5575                 Exit Do
5576             End If
5577         Loop While True
5578         Dim mv As Boolean = False
5579         With Block
5580             '移動するか?
5581             Dim _tmp As String = String.Format(My.Resources.IDRuleMenuItem_ClickText4, Environment.NewLine)
5582             If MessageBox.Show(_tmp, My.Resources.IDRuleMenuItem_ClickText5, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
5583                 mv = False
5584             Else
5585                 mv = True
5586             End If
5587         End With
5588         Dim mk As Boolean = False
5589         If Not mv Then
5590             'マークするか?
5591             Dim _tmp As String = String.Format(My.Resources.IDRuleMenuItem_ClickText6, vbCrLf)
5592             If MessageBox.Show(_tmp, My.Resources.IDRuleMenuItem_ClickText7, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
5593                 mk = True
5594             Else
5595                 mk = False
5596             End If
5597         End If
5598         Dim ids As New List(Of String)
5599         For Each idx As Integer In _curList.SelectedIndices
5600             Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
5601             If Not ids.Contains(post.Name) Then
5602                 Dim fc As New FiltersClass
5603                 ids.Add(post.Name)
5604                 If post.RetweetedId = 0 Then
5605                     fc.NameFilter = post.Name
5606                 Else
5607                     fc.NameFilter = post.RetweetedBy
5608                 End If
5609                 fc.SearchBoth = True
5610                 fc.MoveFrom = mv
5611                 fc.SetMark = mk
5612                 fc.UseRegex = False
5613                 fc.SearchUrl = False
5614                 _statuses.Tabs(tabName).AddFilter(fc)
5615             End If
5616         Next
5617
5618         Try
5619             Me.Cursor = Cursors.WaitCursor
5620             _itemCache = Nothing
5621             _postCache = Nothing
5622             _curPost = Nothing
5623             _curItemIndex = -1
5624             _statuses.FilterAll()
5625             For Each tb As TabPage In ListTab.TabPages
5626                 DirectCast(tb.Tag, DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
5627                 If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
5628                     If SettingDialog.TabIconDisp Then
5629                         tb.ImageIndex = 0
5630                     End If
5631                 Else
5632                     If SettingDialog.TabIconDisp Then
5633                         tb.ImageIndex = -1
5634                     End If
5635                 End If
5636             Next
5637             If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
5638         Finally
5639             Me.Cursor = Cursors.Default
5640         End Try
5641         SaveConfigsCommon()
5642         'SaveConfigsTab(False)
5643         SaveConfigsTabs()
5644     End Sub
5645
5646     Private Sub CopySTOTMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CopySTOTMenuItem.Click
5647         Me.CopyStot()
5648     End Sub
5649
5650     Private Sub CopyURLMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CopyURLMenuItem.Click
5651         Me.CopyIdUri()
5652     End Sub
5653
5654     Private Sub SelectAllMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectAllMenuItem.Click
5655         If StatusText.Focused Then
5656             ' 発言欄でのCtrl+A
5657             StatusText.SelectAll()
5658         Else
5659             ' ListView上でのCtrl+A
5660             For i As Integer = 0 To _curList.VirtualListSize - 1
5661                 _curList.SelectedIndices.Add(i)
5662             Next
5663         End If
5664     End Sub
5665
5666     Private Sub MoveMiddle()
5667         Dim _item As ListViewItem
5668         Dim idx1 As Integer
5669         Dim idx2 As Integer
5670
5671         If _curList.SelectedIndices.Count = 0 Then Exit Sub
5672
5673         Dim idx As Integer = _curList.SelectedIndices(0)
5674
5675         _item = _curList.GetItemAt(0, 25)
5676         If _item Is Nothing Then
5677             idx1 = 0
5678         Else
5679             idx1 = _item.Index
5680         End If
5681         _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1)
5682         If _item Is Nothing Then
5683             idx2 = _curList.VirtualListSize - 1
5684         Else
5685             idx2 = _item.Index
5686         End If
5687
5688         idx -= Math.Abs(idx1 - idx2) \ 2
5689         If idx < 0 Then idx = 0
5690
5691         _curList.EnsureVisible(_curList.VirtualListSize - 1)
5692         _curList.EnsureVisible(idx)
5693     End Sub
5694
5695     Private Sub WedataMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles WedataMenuItem.Click
5696         Twitter.GetWedata()
5697     End Sub
5698
5699     Private Sub OpenURLMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenURLMenuItem.Click
5700         If PostBrowser.Document.Links.Count > 0 Then
5701             UrlDialog.ClearUrl()
5702
5703             Dim openUrlStr As String = ""
5704
5705             If PostBrowser.Document.Links.Count = 1 Then
5706                 Dim urlStr As String = ""
5707                 Try
5708                     urlStr = IDNDecode(PostBrowser.Document.Links(0).GetAttribute("href"))
5709                 Catch ex As ArgumentException
5710                     '変なHTML?
5711                     Exit Sub
5712                 End Try
5713                 If String.IsNullOrEmpty(urlStr) Then Exit Sub
5714                 openUrlStr = urlEncodeMultibyteChar(urlStr)
5715             Else
5716                 For Each linkElm As HtmlElement In PostBrowser.Document.Links
5717                     Dim urlStr As String = ""
5718                     Try
5719                         urlStr = IDNDecode(linkElm.GetAttribute("href"))
5720                     Catch ex As ArgumentException
5721                         '変なHTML?
5722                         Exit Sub
5723                     End Try
5724                     If String.IsNullOrEmpty(urlStr) Then Continue For
5725                     UrlDialog.AddUrl(urlEncodeMultibyteChar(urlStr))
5726                 Next
5727                 Try
5728                     If UrlDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
5729                         openUrlStr = UrlDialog.SelectedUrl
5730                     End If
5731                 Catch ex As Exception
5732                     Exit Sub
5733                 End Try
5734                 Me.TopMost = SettingDialog.AlwaysTop
5735             End If
5736             If String.IsNullOrEmpty(openUrlStr) Then Exit Sub
5737             openUrlStr = openUrlStr.Replace("://twitter.com/search?q=#", "://twitter.com/search?q=%23")
5738             OpenUriAsync(openUrlStr)
5739         End If
5740     End Sub
5741
5742     Private Sub ClearTabMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ClearTabMenuItem.Click
5743         If _rclickTabName = "" Then Exit Sub
5744         Dim tmp As String = String.Format(My.Resources.ClearTabMenuItem_ClickText1, Environment.NewLine)
5745         If MessageBox.Show(tmp, My.Resources.ClearTabMenuItem_ClickText2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
5746             Exit Sub
5747         End If
5748
5749         _statuses.ClearTabIds(_rclickTabName)
5750         If ListTab.SelectedTab.Text = _rclickTabName Then
5751             _anchorPost = Nothing
5752             _anchorFlag = False
5753             _itemCache = Nothing
5754             _postCache = Nothing
5755             _itemCacheIndex = -1
5756             _curItemIndex = -1
5757             _curPost = Nothing
5758         End If
5759         For Each tb As TabPage In ListTab.TabPages
5760             If tb.Text = _rclickTabName Then
5761                 tb.ImageIndex = -1
5762                 DirectCast(tb.Tag, DetailsListView).VirtualListSize = 0
5763                 Exit For
5764             End If
5765         Next
5766         If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
5767
5768         SetMainWindowTitle()
5769         SetStatusLabel()
5770     End Sub
5771
5772     Private Sub SetMainWindowTitle()
5773         'メインウインドウタイトルの書き換え
5774         Dim ttl As New StringBuilder(256)
5775         Dim ur As Integer = 0
5776         Dim al As Integer = 0
5777         Static myVer As String = fileVersion
5778         If SettingDialog.DispLatestPost <> DispTitleEnum.None AndAlso _
5779            SettingDialog.DispLatestPost <> DispTitleEnum.Post AndAlso _
5780            SettingDialog.DispLatestPost <> DispTitleEnum.Ver Then
5781             For Each key As String In _statuses.Tabs.Keys
5782                 ur += _statuses.Tabs(key).UnreadCount
5783                 al += _statuses.Tabs(key).AllCount
5784             Next
5785         End If
5786
5787         If SettingDialog.DispUsername Then ttl.Append(_username).Append(" - ")
5788         ttl.Append("Tween  ")
5789         Select Case SettingDialog.DispLatestPost
5790             Case DispTitleEnum.Ver
5791                 ttl.Append("Ver:").Append(myVer)
5792             Case DispTitleEnum.Post
5793                 If _history IsNot Nothing AndAlso _history.Count > 1 Then
5794                     ttl.Append(_history(_history.Count - 2).Replace(vbCrLf, ""))
5795                 End If
5796             Case DispTitleEnum.UnreadRepCount
5797                 ttl.AppendFormat(My.Resources.SetMainWindowTitleText1, _statuses.GetTabByType(TabUsageType.Mentions).UnreadCount + _statuses.GetTabByType(TabUsageType.DirectMessage).UnreadCount)
5798             Case DispTitleEnum.UnreadAllCount
5799                 ttl.AppendFormat(My.Resources.SetMainWindowTitleText2, ur)
5800             Case DispTitleEnum.UnreadAllRepCount
5801                 ttl.AppendFormat(My.Resources.SetMainWindowTitleText3, ur, _statuses.GetTabByType(TabUsageType.Mentions).UnreadCount + _statuses.GetTabByType(TabUsageType.DirectMessage).UnreadCount)
5802             Case DispTitleEnum.UnreadCountAllCount
5803                 ttl.AppendFormat(My.Resources.SetMainWindowTitleText4, ur, al)
5804         End Select
5805
5806         Try
5807             Me.Text = ttl.ToString()
5808         Catch ex As AccessViolationException
5809             '原因不明。ポスト内容に依存か?たまーに発生するが再現せず。
5810         End Try
5811     End Sub
5812
5813     Private Sub SetStatusLabel()
5814         'ステータス欄にカウント表示
5815         'タブ未読数/タブ発言数 全未読数/総発言数 (未読@+未読DM数)
5816         If _statuses Is Nothing Then Exit Sub
5817         Dim urat As Integer = _statuses.GetTabByType(TabUsageType.Mentions).UnreadCount + _statuses.GetTabByType(TabUsageType.DirectMessage).UnreadCount
5818         Dim ur As Integer = 0
5819         Dim al As Integer = 0
5820         Dim tur As Integer = 0
5821         Dim tal As Integer = 0
5822         Dim slbl As StringBuilder = New StringBuilder(256)
5823         For Each key As String In _statuses.Tabs.Keys
5824             ur += _statuses.Tabs(key).UnreadCount
5825             al += _statuses.Tabs(key).AllCount
5826             If key.Equals(_curTab.Text) Then
5827                 tur = _statuses.Tabs(key).UnreadCount
5828                 tal = _statuses.Tabs(key).AllCount
5829             End If
5830         Next
5831
5832         slbl.AppendFormat(My.Resources.SetStatusLabelText1, tur, tal, ur, al, urat, _postTimestamps.Count, _favTimestamps.Count, _tlCount)
5833         If SettingDialog.TimelinePeriodInt = 0 Then
5834             slbl.Append(My.Resources.SetStatusLabelText2)
5835         Else
5836             slbl.Append((TimerTimeline.Interval / 1000).ToString() + My.Resources.SetStatusLabelText3)
5837         End If
5838         If Twitter.RemainCountApi > -1 AndAlso SettingDialog.UseAPI Then
5839             slbl.Append(" [API: " + Twitter.RemainCountApi.ToString + "]")
5840         End If
5841
5842         StatusLabelUrl.Text = slbl.ToString()
5843     End Sub
5844
5845     Private Sub SetNotifyIconText()
5846         ' タスクトレイアイコンのツールチップテキスト書き換え
5847         If SettingDialog.DispUsername Then
5848             NotifyIcon1.Text = _username + " - Tween"
5849         Else
5850             NotifyIcon1.Text = "Tween"
5851         End If
5852     End Sub
5853
5854     Friend Sub CheckReplyTo(ByVal StatusText As String)
5855         ' 本当にリプライ先指定すべきかどうかの判定
5856         Dim id As New Regex("(^|[ -/:-@[-^`{-~])(?<id>@[a-zA-Z0-9_]+)")
5857         Dim m As MatchCollection
5858
5859         m = id.Matches(StatusText)
5860
5861         If AtIdSupl IsNot Nothing Then
5862             Dim bCnt As Integer = AtIdSupl.IdCount
5863             For Each mid As Match In m
5864                 AtIdSupl.AddId(mid.Result("${id}"))
5865             Next
5866             If bCnt <> AtIdSupl.IdCount Then modifySettingAtId = True
5867         End If
5868
5869         ' リプライ先ステータスIDの指定がない場合は指定しない
5870         If _reply_to_id = 0 Then Exit Sub
5871
5872         ' リプライ先ユーザー名がない場合も指定しない
5873         If _reply_to_name = "" Then
5874             _reply_to_id = 0
5875             Exit Sub
5876         End If
5877
5878         ' 通常Reply
5879         ' 次の条件を満たす場合に in_reply_to_status_id 指定
5880         ' 1. Twitterによりリンクと判定される @idが文中に1つ含まれる (2009/5/28 リンク化される@IDのみカウントするように修正)
5881         ' 2. リプライ先ステータスIDが設定されている(リストをダブルクリックで返信している)
5882         ' 3. 文中に含まれた@idがリプライ先のポスト者のIDと一致する
5883
5884         If m IsNot Nothing AndAlso Not StatusText.StartsWith(". ") Then
5885             For Each mid As Match In m
5886                 If mid.Result("${id}") = "@" + _reply_to_name Then
5887                     Exit Sub
5888                 End If
5889             Next
5890         End If
5891         'If m IsNot Nothing AndAlso m.Count = 1 AndAlso m.Item(0).Value = "@" + _reply_to_name AndAlso Not StatusText.StartsWith(". ") Then
5892         '    Exit Sub
5893         'End If
5894
5895         _reply_to_id = 0
5896         _reply_to_name = ""
5897
5898     End Sub
5899
5900     Private Sub TweenMain_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Resize
5901         If SettingDialog.MinimizeToTray AndAlso WindowState = FormWindowState.Minimized Then
5902             Me.Visible = False
5903         End If
5904     End Sub
5905
5906     Private Sub PlaySoundMenuItem_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PlaySoundMenuItem.CheckedChanged
5907         If PlaySoundMenuItem.Checked Then
5908             SettingDialog.PlaySound = True
5909         Else
5910             SettingDialog.PlaySound = False
5911         End If
5912         modifySettingCommon = True
5913         'SaveConfigsCommon()
5914     End Sub
5915
5916     Private Sub SplitContainer1_SplitterMoved(ByVal sender As Object, ByVal e As System.Windows.Forms.SplitterEventArgs) Handles SplitContainer1.SplitterMoved
5917         If Me.WindowState = FormWindowState.Normal Then
5918             _mySpDis = SplitContainer1.SplitterDistance
5919             If StatusText.Multiline Then _mySpDis2 = StatusText.Height
5920             modifySettingLocal = True
5921         End If
5922     End Sub
5923
5924     Private Sub RepliedStatusOpenMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RepliedStatusOpenMenuItem.Click
5925         If _curPost IsNot Nothing AndAlso _curPost.InReplyToUser IsNot Nothing AndAlso _curPost.InReplyToId > 0 Then
5926             If _statuses.ContainsKey(_curPost.InReplyToId) AndAlso Not My.Computer.Keyboard.ShiftKeyDown Then
5927                 Dim repPost As PostClass = _statuses.Item(_curPost.InReplyToId)
5928                 MessageBox.Show(repPost.Name + " / " + repPost.Nickname + "   (" + repPost.PDate.ToString() + ")" + Environment.NewLine + repPost.Data)
5929             Else
5930                 OpenUriAsync("http://twitter.com/" + _curPost.InReplyToUser + "/status/" + _curPost.InReplyToId.ToString())
5931             End If
5932         End If
5933     End Sub
5934
5935     Private Sub ContextMenuStrip3_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip3.Opening
5936         '発言詳細のアイコン右クリック時のメニュー制御
5937         If _curList.SelectedIndices.Count > 0 AndAlso _curPost IsNot Nothing Then
5938             Dim name As String = _curPost.ImageUrl
5939             If name.Length > 0 Then
5940                 name = IO.Path.GetFileNameWithoutExtension(name.Substring(name.LastIndexOf("/"c)))
5941                 name = name.Substring(0, name.Length - 7) ' "_normal".Length
5942                 Me.IconNameToolStripMenuItem.Enabled = True
5943                 If Me.TIconDic.ContainsKey(_curPost.ImageUrl) AndAlso Me.TIconDic(_curPost.ImageUrl) IsNot Nothing Then
5944                     Me.SaveIconPictureToolStripMenuItem.Enabled = True
5945                 Else
5946                     Me.SaveIconPictureToolStripMenuItem.Enabled = False
5947                 End If
5948                 Me.IconNameToolStripMenuItem.Text = name
5949             Else
5950                 Me.IconNameToolStripMenuItem.Enabled = False
5951                 Me.SaveIconPictureToolStripMenuItem.Enabled = False
5952                 Me.IconNameToolStripMenuItem.Text = My.Resources.ContextMenuStrip3_OpeningText1
5953             End If
5954         Else
5955             Me.IconNameToolStripMenuItem.Enabled = False
5956             Me.SaveIconPictureToolStripMenuItem.Enabled = False
5957             Me.IconNameToolStripMenuItem.Text = My.Resources.ContextMenuStrip3_OpeningText2
5958         End If
5959     End Sub
5960
5961     Private Sub IconNameToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IconNameToolStripMenuItem.Click
5962         If _curPost Is Nothing Then Exit Sub
5963         Dim name As String = _curPost.ImageUrl
5964         OpenUriAsync(name.Remove(name.LastIndexOf("_normal"), 7)) ' "_normal".Length
5965     End Sub
5966
5967     Private Sub SaveOriginalSizeIconPictureToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
5968         If _curPost Is Nothing Then Exit Sub
5969         Dim name As String = _curPost.ImageUrl
5970         name = IO.Path.GetFileNameWithoutExtension(name.Substring(name.LastIndexOf("/"c)))
5971
5972         Me.SaveFileDialog1.FileName = name.Substring(0, name.Length - 8) ' "_normal".Length + 1
5973
5974         If Me.SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
5975             ' STUB
5976         End If
5977     End Sub
5978
5979     Private Sub SaveIconPictureToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveIconPictureToolStripMenuItem.Click
5980         If _curPost Is Nothing Then Exit Sub
5981         Dim name As String = _curPost.ImageUrl
5982
5983         Me.SaveFileDialog1.FileName = name.Substring(name.LastIndexOf("/"c) + 1)
5984
5985         If Me.SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
5986             Using bmp2 As New Bitmap(TIconDic(name).Size.Width, TIconDic(name).Size.Height)
5987                 Using g As Graphics = Graphics.FromImage(bmp2)
5988                     g.InterpolationMode = Drawing2D.InterpolationMode.High
5989                     g.DrawImage(TIconDic(name), 0, 0, TIconDic(name).Size.Width, TIconDic(name).Size.Height)
5990                     g.Dispose()
5991                 End Using
5992                 bmp2.Save(Me.SaveFileDialog1.FileName)
5993                 bmp2.Dispose()
5994             End Using
5995         End If
5996     End Sub
5997
5998     Private Sub SplitContainer2_Panel2_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SplitContainer2.Panel2.Resize
5999         Me.StatusText.Multiline = Me.SplitContainer2.Panel2.Height > Me.SplitContainer2.Panel2MinSize + 2
6000         MultiLineMenuItem.Checked = Me.StatusText.Multiline
6001         modifySettingLocal = True
6002     End Sub
6003
6004     Private Sub StatusText_MultilineChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusText.MultilineChanged
6005         If Me.StatusText.Multiline Then
6006             Me.StatusText.ScrollBars = ScrollBars.Vertical
6007         Else
6008             Me.StatusText.ScrollBars = ScrollBars.None
6009         End If
6010         modifySettingLocal = True
6011     End Sub
6012
6013     Private Sub MultiLineMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MultiLineMenuItem.Click
6014         '発言欄複数行
6015         StatusText.Multiline = MultiLineMenuItem.Checked
6016         _cfgLocal.StatusMultiline = MultiLineMenuItem.Checked
6017         If MultiLineMenuItem.Checked Then
6018             If SplitContainer2.Height - _mySpDis2 - SplitContainer2.SplitterWidth < 0 Then
6019                 SplitContainer2.SplitterDistance = 0
6020             Else
6021                 SplitContainer2.SplitterDistance = SplitContainer2.Height - _mySpDis2 - SplitContainer2.SplitterWidth
6022             End If
6023         Else
6024             SplitContainer2.SplitterDistance = SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth
6025         End If
6026         modifySettingLocal = True
6027     End Sub
6028
6029     Private Function UrlConvert(ByVal Converter_Type As UrlConverter) As Boolean
6030         Dim result As String = ""
6031         Dim url As Regex = New Regex("(?<![0-9A-Za-z])(?:https?|shttp)://(?:(?:[-_.!~*'()a-zA-Z0-9;:&=+$,]|%[0-9A-Fa-f" + _
6032                                      "][0-9A-Fa-f])*@)?(?:(?:[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?\.)" + _
6033                                      "*[a-zA-Z](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?\.?|[0-9]+\.[0-9]+\.[0-9]+\." + _
6034                                      "[0-9]+)(?::[0-9]*)?(?:/(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f]" + _
6035                                      "[0-9A-Fa-f])*(?:;(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-" + _
6036                                      "Fa-f])*)*(?:/(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f" + _
6037                                      "])*(?:;(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)*)" + _
6038                                      "*)?(?:\?(?:[-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])" + _
6039                                      "*)?(?:#(?:[-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)?")
6040
6041
6042         If StatusText.SelectionLength > 0 Then
6043             Dim tmp As String = StatusText.SelectedText
6044             ' httpから始まらない場合、ExcludeStringで指定された文字列で始まる場合は対象としない
6045             If tmp.StartsWith("http") Then
6046                 ' 文字列が選択されている場合はその文字列について処理
6047
6048                 '短縮URL変換 日本語を含むかもしれないのでURLエンコードする
6049                 result = Twitter.MakeShortUrl(Converter_Type, StatusText.SelectedText)
6050
6051                 If result.Equals("Can't convert") Then
6052                     StatusLabel.Text = result.Insert(0, Converter_Type.ToString() + ":")
6053                     Return False
6054                 End If
6055
6056                 If Not result = "" Then
6057                     Dim undotmp As New urlUndo
6058
6059                     StatusText.Select(StatusText.Text.IndexOf(tmp, StringComparison.Ordinal), tmp.Length)
6060                     StatusText.SelectedText = result
6061
6062                     'undoバッファにセット
6063                     undotmp.Before = tmp
6064                     undotmp.After = result
6065
6066                     If urlUndoBuffer Is Nothing Then
6067                         urlUndoBuffer = New List(Of urlUndo)
6068                         UrlUndoToolStripMenuItem.Enabled = True
6069                     End If
6070
6071                     urlUndoBuffer.Add(undotmp)
6072                 End If
6073             End If
6074         Else
6075             Dim urls As RegularExpressions.MatchCollection = Nothing
6076             urls = url.Matches(StatusText.Text)
6077
6078             ' 正規表現にマッチしたURL文字列をtinyurl化
6079             For Each tmp2 As Match In urls
6080                 Dim tmp As String = tmp2.ToString
6081                 Dim undotmp As New urlUndo
6082
6083                 '選んだURLを選択(?)
6084                 StatusText.Select(StatusText.Text.IndexOf(tmp, StringComparison.Ordinal), tmp.Length)
6085
6086                 '短縮URL変換
6087                 result = Twitter.MakeShortUrl(Converter_Type, StatusText.SelectedText)
6088
6089                 If result.Equals("Can't convert") Then
6090                     StatusLabel.Text = result.Insert(0, Converter_Type.ToString() + ":")
6091                     Continue For
6092                 End If
6093
6094                 If Not result = "" Then
6095                     StatusText.Select(StatusText.Text.IndexOf(tmp, StringComparison.Ordinal), tmp.Length)
6096                     StatusText.SelectedText = result
6097                     'undoバッファにセット
6098                     undotmp.Before = tmp
6099                     undotmp.After = result
6100
6101                     If urlUndoBuffer Is Nothing Then
6102                         urlUndoBuffer = New List(Of urlUndo)
6103                         UrlUndoToolStripMenuItem.Enabled = True
6104                     End If
6105
6106                     urlUndoBuffer.Add(undotmp)
6107                 End If
6108             Next
6109         End If
6110
6111         Return True
6112
6113     End Function
6114
6115     Private Sub doUrlUndo()
6116         If urlUndoBuffer IsNot Nothing Then
6117             Dim tmp As String = StatusText.Text
6118             For Each data As urlUndo In urlUndoBuffer
6119                 tmp = tmp.Replace(data.After, data.Before)
6120             Next
6121             StatusText.Text = tmp
6122             urlUndoBuffer = Nothing
6123             UrlUndoToolStripMenuItem.Enabled = False
6124         End If
6125     End Sub
6126
6127     Private Sub TinyURLToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TinyURLToolStripMenuItem.Click
6128         UrlConvert(UrlConverter.TinyUrl)
6129     End Sub
6130
6131     Private Sub IsgdToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IsgdToolStripMenuItem.Click
6132         UrlConvert(UrlConverter.Isgd)
6133     End Sub
6134
6135     Private Sub TwurlnlToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TwurlnlToolStripMenuItem.Click
6136         UrlConvert(UrlConverter.Twurl)
6137     End Sub
6138
6139     Private Sub UrlConvertAutoToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UrlConvertAutoToolStripMenuItem.Click
6140         If Not UrlConvert(SettingDialog.AutoShortUrlFirst) Then
6141             Dim svc As UrlConverter = SettingDialog.AutoShortUrlFirst
6142             Dim rnd As New Random()
6143             ' 前回使用した短縮URLサービス以外を選択する
6144             Do
6145                 svc = CType(rnd.Next(System.Enum.GetNames(GetType(UrlConverter)).Length), UrlConverter)
6146             Loop Until svc <> SettingDialog.AutoShortUrlFirst
6147             UrlConvert(svc)
6148         End If
6149     End Sub
6150
6151     Private Sub UrlUndoToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UrlUndoToolStripMenuItem.Click
6152         doUrlUndo()
6153     End Sub
6154
6155     Private Sub NewPostPopMenuItem_CheckStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles NewPostPopMenuItem.CheckStateChanged
6156         _cfgCommon.NewAllPop = NewPostPopMenuItem.Checked
6157         modifySettingCommon = True
6158     End Sub
6159
6160     Private Sub ListLockMenuItem_CheckStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListLockMenuItem.CheckStateChanged
6161         _cfgCommon.ListLock = ListLockMenuItem.Checked
6162         modifySettingCommon = True
6163     End Sub
6164
6165     Private Sub MenuStrip1_MenuActivate(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuStrip1.MenuActivate
6166         ' フォーカスがメニューに移る (MenuStrip1.Tag フラグを立てる)
6167         MenuStrip1.Tag = New Object()
6168         MenuStrip1.Select() ' StatusText がフォーカスを持っている場合 Leave が発生
6169     End Sub
6170
6171     Private Sub MenuStrip1_MenuDeactivate(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuStrip1.MenuDeactivate
6172         If Me.Tag IsNot Nothing Then ' 設定された戻り先へ遷移
6173             DirectCast(Me.Tag, Control).Select()
6174         Else ' 戻り先が指定されていない (初期状態) 場合はタブに遷移
6175             If ListTab.SelectedIndex > -1 AndAlso ListTab.SelectedTab.HasChildren Then
6176                 Me.Tag = ListTab.SelectedTab.Tag
6177                 DirectCast(Me.Tag, Control).Select()
6178             End If
6179         End If
6180         ' フォーカスがメニューに遷移したかどうかを表すフラグを降ろす
6181         MenuStrip1.Tag = Nothing
6182     End Sub
6183
6184     Private Sub MyList_ColumnReordered(ByVal sender As System.Object, ByVal e As ColumnReorderedEventArgs)
6185         Dim lst As DetailsListView = DirectCast(sender, DetailsListView)
6186         If _cfgLocal Is Nothing Then Exit Sub
6187
6188         If _iconCol Then
6189             _cfgLocal.Width1 = lst.Columns(0).Width
6190             _cfgLocal.Width3 = lst.Columns(1).Width
6191         Else
6192             Dim darr(lst.Columns.Count - 1) As Integer
6193             For i As Integer = 0 To lst.Columns.Count - 1
6194                 darr(lst.Columns(i).DisplayIndex) = i
6195             Next
6196             MoveArrayItem(darr, e.OldDisplayIndex, e.NewDisplayIndex)
6197
6198             For i As Integer = 0 To lst.Columns.Count - 1
6199                 Select Case darr(i)
6200                     Case 0
6201                         _cfgLocal.DisplayIndex1 = i
6202                     Case 1
6203                         _cfgLocal.DisplayIndex2 = i
6204                     Case 2
6205                         _cfgLocal.DisplayIndex3 = i
6206                     Case 3
6207                         _cfgLocal.DisplayIndex4 = i
6208                     Case 4
6209                         _cfgLocal.DisplayIndex5 = i
6210                     Case 5
6211                         _cfgLocal.DisplayIndex6 = i
6212                     Case 6
6213                         _cfgLocal.DisplayIndex7 = i
6214                     Case 7
6215                         _cfgLocal.DisplayIndex8 = i
6216                 End Select
6217             Next
6218             _cfgLocal.Width1 = lst.Columns(0).Width
6219             _cfgLocal.Width2 = lst.Columns(1).Width
6220             _cfgLocal.Width3 = lst.Columns(2).Width
6221             _cfgLocal.Width4 = lst.Columns(3).Width
6222             _cfgLocal.Width5 = lst.Columns(4).Width
6223             _cfgLocal.Width6 = lst.Columns(5).Width
6224             _cfgLocal.Width7 = lst.Columns(6).Width
6225             _cfgLocal.Width8 = lst.Columns(7).Width
6226         End If
6227         modifySettingLocal = True
6228     End Sub
6229
6230     Private Sub MyList_ColumnWidthChanged(ByVal sender As System.Object, ByVal e As ColumnWidthChangedEventArgs)
6231         Dim lst As DetailsListView = DirectCast(sender, DetailsListView)
6232         'Dim changed As Boolean = False
6233         If _cfgLocal Is Nothing Then Exit Sub
6234         If _iconCol Then
6235             If _cfgLocal.Width1 <> lst.Columns(0).Width Then
6236                 _cfgLocal.Width1 = lst.Columns(0).Width
6237                 modifySettingLocal = True
6238             End If
6239             If _cfgLocal.Width3 <> lst.Columns(1).Width Then
6240                 _cfgLocal.Width3 = lst.Columns(1).Width
6241                 modifySettingLocal = True
6242             End If
6243         Else
6244             If _cfgLocal.Width1 <> lst.Columns(0).Width Then
6245                 _cfgLocal.Width1 = lst.Columns(0).Width
6246                 modifySettingLocal = True
6247             End If
6248             If _cfgLocal.Width2 <> lst.Columns(1).Width Then
6249                 _cfgLocal.Width2 = lst.Columns(1).Width
6250                 modifySettingLocal = True
6251             End If
6252             If _cfgLocal.Width3 <> lst.Columns(2).Width Then
6253                 _cfgLocal.Width3 = lst.Columns(2).Width
6254                 modifySettingLocal = True
6255             End If
6256             If _cfgLocal.Width4 <> lst.Columns(3).Width Then
6257                 _cfgLocal.Width4 = lst.Columns(3).Width
6258                 modifySettingLocal = True
6259             End If
6260             If _cfgLocal.Width5 <> lst.Columns(4).Width Then
6261                 _cfgLocal.Width5 = lst.Columns(4).Width
6262                 modifySettingLocal = True
6263             End If
6264             If _cfgLocal.Width6 <> lst.Columns(5).Width Then
6265                 _cfgLocal.Width6 = lst.Columns(5).Width
6266                 modifySettingLocal = True
6267             End If
6268             If _cfgLocal.Width7 <> lst.Columns(6).Width Then
6269                 _cfgLocal.Width7 = lst.Columns(6).Width
6270                 modifySettingLocal = True
6271             End If
6272             If _cfgLocal.Width8 <> lst.Columns(7).Width Then
6273                 _cfgLocal.Width8 = lst.Columns(7).Width
6274                 modifySettingLocal = True
6275             End If
6276         End If
6277         ' 非表示の時にColumnChangedが呼ばれた場合はForm初期化処理中なので保存しない
6278         'If changed Then
6279         '    SaveConfigsLocal()
6280         'End If
6281     End Sub
6282
6283     Private Sub ToolStripMenuItem3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem3.Click
6284         '発言詳細で「選択文字列をコピー」
6285         'PostBrowser.Document.ExecCommand("Copy", False, Nothing)
6286         'SendKeys.Send("^c")
6287         Dim typ As Type = PostBrowser.ActiveXInstance.GetType()
6288         Dim _SelObj As Object = typ.InvokeMember("selection", BindingFlags.GetProperty, Nothing, PostBrowser.Document.DomDocument, Nothing)
6289         Dim _objRange As Object = _SelObj.GetType().InvokeMember("createRange", BindingFlags.InvokeMethod, Nothing, _SelObj, Nothing)
6290         Dim _selText As String = DirectCast(_objRange.GetType().InvokeMember("text", BindingFlags.GetProperty, Nothing, _objRange, Nothing), String)
6291         Clipboard.SetDataObject(_selText, False, 5, 100)
6292     End Sub
6293
6294     Private Sub doSearchToolStrip(ByVal url As String)
6295         '発言詳細で「選択文字列で検索」(選択文字列取得)
6296         Dim typ As Type = PostBrowser.ActiveXInstance.GetType()
6297         Dim _SelObj As Object = typ.InvokeMember("selection", BindingFlags.GetProperty, Nothing, PostBrowser.Document.DomDocument, Nothing)
6298         Dim _objRange As Object = _SelObj.GetType().InvokeMember("createRange", BindingFlags.InvokeMethod, Nothing, _SelObj, Nothing)
6299         Dim _selText As String = DirectCast(_objRange.GetType().InvokeMember("text", BindingFlags.GetProperty, Nothing, _objRange, Nothing), String)
6300         Dim tmp As String
6301
6302         If _selText IsNot Nothing Then
6303             tmp = String.Format(url, HttpUtility.UrlEncode(_selText))
6304             OpenUriAsync(tmp)
6305         End If
6306     End Sub
6307
6308     Private Sub ToolStripMenuItem5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem5.Click
6309         '発言詳細ですべて選択
6310         PostBrowser.Document.ExecCommand("SelectAll", False, Nothing)
6311     End Sub
6312
6313     Private Sub SearchItem1ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchItem1ToolStripMenuItem.Click
6314         doSearchToolStrip(My.Resources.SearchItem1Url)
6315     End Sub
6316
6317     Private Sub SearchItem2ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchItem2ToolStripMenuItem.Click
6318         doSearchToolStrip(My.Resources.SearchItem2Url)
6319     End Sub
6320
6321     Private Sub SearchItem3ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchItem3ToolStripMenuItem.Click
6322         doSearchToolStrip(My.Resources.SearchItem3Url)
6323     End Sub
6324
6325     Private Sub SearchItem4ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchItem4ToolStripMenuItem.Click
6326         doSearchToolStrip(My.Resources.SearchItem4Url)
6327     End Sub
6328
6329     Private Sub ToolStripMenuItem4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem4.Click
6330         'URLをコピー
6331         'If PostBrowser.StatusText.StartsWith("http") Then   '念のため
6332         Clipboard.SetDataObject(PostBrowser.StatusText, False, 5, 100)
6333         'End If
6334     End Sub
6335
6336     Private Sub ContextMenuStrip4_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip4.Opening
6337         ' URLコピーの項目の表示/非表示
6338         If PostBrowser.StatusText.StartsWith("http") Then
6339             ToolStripMenuItem4.Enabled = True
6340             If Regex.IsMatch(PostBrowser.StatusText, "^https?://twitter.com/[a-zA-Z0-9_]+$") Then
6341                 FollowContextMenuItem.Enabled = True
6342                 RemoveContextMenuItem.Enabled = True
6343                 FriendshipContextMenuItem.Enabled = True
6344             Else
6345                 FollowContextMenuItem.Enabled = False
6346                 RemoveContextMenuItem.Enabled = False
6347                 FriendshipContextMenuItem.Enabled = False
6348             End If
6349         Else
6350             ToolStripMenuItem4.Enabled = False
6351             FollowContextMenuItem.Enabled = False
6352             RemoveContextMenuItem.Enabled = False
6353             FriendshipContextMenuItem.Enabled = False
6354         End If
6355         ' 文字列選択されていないときは選択文字列関係の項目を非表示に
6356         Dim _selText As String = PostBrowser_GetSelectionText()
6357         If _selText Is Nothing Then
6358             ToolStripMenuItem2.Enabled = False
6359             ToolStripMenuItem3.Enabled = False
6360         Else
6361             ToolStripMenuItem2.Enabled = True
6362             ToolStripMenuItem3.Enabled = True
6363         End If
6364         e.Cancel = False
6365     End Sub
6366
6367     Private Function PostBrowser_GetSelectionText() As String
6368         Dim typ As Type = PostBrowser.ActiveXInstance.GetType()
6369         Dim _SelObj As Object = typ.InvokeMember("selection", BindingFlags.GetProperty, Nothing, PostBrowser.Document.DomDocument, Nothing)
6370         Dim _objRange As Object = _SelObj.GetType().InvokeMember("createRange", BindingFlags.InvokeMethod, Nothing, _SelObj, Nothing)
6371         Return DirectCast(_objRange.GetType().InvokeMember("text", BindingFlags.GetProperty, Nothing, _objRange, Nothing), String)
6372     End Function
6373
6374     Private Sub CurrentTabToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CurrentTabToolStripMenuItem.Click
6375         '発言詳細の選択文字列で現在のタブを検索
6376         Dim _selText As String = PostBrowser_GetSelectionText()
6377
6378         If _selText IsNot Nothing Then
6379             SearchDialog.SWord = _selText
6380             SearchDialog.CheckCaseSensitive = False
6381             SearchDialog.CheckRegex = False
6382
6383             DoTabSearch(SearchDialog.SWord, _
6384                         SearchDialog.CheckCaseSensitive, _
6385                         SearchDialog.CheckRegex, _
6386                         SEARCHTYPE.NextSearch)
6387         End If
6388     End Sub
6389
6390     Private Sub SplitContainer2_SplitterMoved(ByVal sender As Object, ByVal e As System.Windows.Forms.SplitterEventArgs) Handles SplitContainer2.SplitterMoved
6391         If StatusText.Multiline Then _mySpDis2 = StatusText.Height
6392         modifySettingLocal = True
6393     End Sub
6394
6395     Private Sub TweenMain_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragDrop
6396         Dim data As String = TryCast(e.Data.GetData(DataFormats.StringFormat, True), String)
6397         If data IsNot Nothing Then
6398             StatusText.Text += data
6399         End If
6400     End Sub
6401
6402     Private Sub TweenMain_DragOver(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragOver
6403         Dim data As String = TryCast(e.Data.GetData(DataFormats.StringFormat, True), String)
6404         If data IsNot Nothing Then
6405             e.Effect = DragDropEffects.Copy
6406         Else
6407             e.Effect = DragDropEffects.None
6408         End If
6409     End Sub
6410
6411     ' Contributed by shuyoko <http://twitter.com/shuyoko> BEGIN:
6412     Private Sub BlackFavAddToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BlackFavAddToolStripMenuItem.Click
6413
6414         Dim cnt As Integer = 0
6415
6416         If _statuses.GetTabByType(TabUsageType.DirectMessage).TabName = _curTab.Text OrElse _curList.SelectedIndices.Count = 0 Then Exit Sub
6417
6418         If _curList.SelectedIndices.Count > 1 Then
6419             If MessageBox.Show(My.Resources.BlackFavAddToolStripMenuItem_ClickText1, My.Resources.BlackFavAddToolStripMenuItem_ClickText2, _
6420                                MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
6421                 Exit Sub
6422             End If
6423         End If
6424
6425         Dim args As New GetWorkerArg()
6426         args.ids = New List(Of Long)
6427         args.sIds = New List(Of Long)
6428         args.tName = _curTab.Text
6429         For Each idx As Integer In _curList.SelectedIndices
6430             If Not _statuses.Item(_curTab.Text, idx).IsFav Then
6431                 args.ids.Add(_statuses.Item(_curTab.Text, idx).Id)
6432             End If
6433         Next
6434         args.type = WORKERTYPE.BlackFavAdd
6435         If args.ids.Count = 0 Then
6436             StatusLabel.Text = My.Resources.BlackFavAddToolStripMenuItem_ClickText4
6437             Exit Sub
6438         End If
6439
6440         RunAsync(args)
6441     End Sub
6442
6443     Private Function IsNetworkAvailable() As Boolean
6444         Dim nw As Boolean = True
6445         Try
6446             nw = My.Computer.Network.IsAvailable
6447         Catch ex As Exception
6448             nw = True
6449         End Try
6450         _myStatusOnline = nw
6451         Return nw
6452     End Function
6453
6454     Private Sub OpenUriAsync(ByVal UriString As String)
6455         Dim args As New GetWorkerArg
6456         args.type = WORKERTYPE.OpenUri
6457         args.status = UriString
6458
6459         RunAsync(args)
6460     End Sub
6461
6462     Private Sub ListTabSelect(ByVal _tab As TabPage)
6463         SetListProperty()
6464
6465         _itemCache = Nothing
6466         _itemCacheIndex = -1
6467         _postCache = Nothing
6468         _curTab = _tab
6469         _curList = DirectCast(_tab.Tag, DetailsListView)
6470         If _curList.SelectedIndices.Count > 0 Then
6471             _curItemIndex = _curList.SelectedIndices(0)
6472             _curPost = GetCurTabPost(_curItemIndex)
6473         Else
6474             _curItemIndex = -1
6475             _curPost = Nothing
6476         End If
6477
6478         _anchorPost = Nothing
6479         _anchorFlag = False
6480     End Sub
6481
6482     Private Sub ListTab_Selecting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TabControlCancelEventArgs) Handles ListTab.Selecting
6483         ListTabSelect(e.TabPage)
6484     End Sub
6485
6486     Private Sub SelectListItem(ByVal LView As DetailsListView, ByVal Index As Integer)
6487         '単一
6488         Dim bnd As Rectangle
6489         Dim flg As Boolean = False
6490         If LView.FocusedItem IsNot Nothing Then
6491             bnd = LView.FocusedItem.Bounds
6492             flg = True
6493         End If
6494
6495         LView.SelectedIndices.Clear()
6496         LView.Items(Index).Selected = True
6497         LView.Items(Index).Focused = True
6498         If flg Then LView.Invalidate(bnd)
6499     End Sub
6500
6501     Private Sub SelectListItem(ByVal LView As DetailsListView, ByVal Index() As Integer, ByVal FocusedIndex As Integer)
6502         '複数
6503         Dim bnd As Rectangle
6504         Dim flg As Boolean = False
6505         If LView.FocusedItem IsNot Nothing Then
6506             bnd = LView.FocusedItem.Bounds
6507             flg = True
6508         End If
6509
6510         If Index IsNot Nothing AndAlso Index(0) > -1 Then
6511             LView.SelectedIndices.Clear()
6512             For Each idx As Integer In Index
6513                 LView.SelectedIndices.Add(idx)
6514             Next
6515         End If
6516         If FocusedIndex > -1 Then
6517             LView.Items(FocusedIndex).Focused = True
6518         End If
6519         If flg Then LView.Invalidate(bnd)
6520     End Sub
6521
6522     Private Sub RunAsync(ByVal args As GetWorkerArg)
6523         Dim bw As BackgroundWorker = Nothing
6524         If args.type <> WORKERTYPE.Follower Then
6525             For i As Integer = 0 To _bw.Length - 1
6526                 If _bw(i) IsNot Nothing AndAlso Not _bw(i).IsBusy Then
6527                     bw = _bw(i)
6528                     Exit For
6529                 End If
6530             Next
6531             If bw Is Nothing Then
6532                 For i As Integer = 0 To _bw.Length - 1
6533                     If _bw(i) Is Nothing Then
6534                         _bw(i) = New BackgroundWorker
6535                         bw = _bw(i)
6536                         bw.WorkerReportsProgress = True
6537                         bw.WorkerSupportsCancellation = True
6538                         AddHandler bw.DoWork, AddressOf GetTimelineWorker_DoWork
6539                         AddHandler bw.ProgressChanged, AddressOf GetTimelineWorker_ProgressChanged
6540                         AddHandler bw.RunWorkerCompleted, AddressOf GetTimelineWorker_RunWorkerCompleted
6541                         Exit For
6542                     End If
6543                 Next
6544             End If
6545         Else
6546             If _bwFollower Is Nothing Then
6547                 _bwFollower = New BackgroundWorker
6548                 bw = _bwFollower
6549                 bw.WorkerReportsProgress = True
6550                 bw.WorkerSupportsCancellation = True
6551                 AddHandler bw.DoWork, AddressOf GetTimelineWorker_DoWork
6552                 AddHandler bw.ProgressChanged, AddressOf GetTimelineWorker_ProgressChanged
6553                 AddHandler bw.RunWorkerCompleted, AddressOf GetTimelineWorker_RunWorkerCompleted
6554             Else
6555                 If _bwFollower.IsBusy = False Then
6556                     bw = _bwFollower
6557                 End If
6558             End If
6559         End If
6560         If bw Is Nothing Then Exit Sub
6561
6562         bw.RunWorkerAsync(args)
6563     End Sub
6564
6565     Private Sub TweenMain_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
6566         Try
6567             PostBrowser.Url = New Uri("about:blank")
6568             PostBrowser.DocumentText = ""       '発言詳細部初期化
6569         Catch ex As Exception
6570
6571         End Try
6572
6573         If IsNetworkAvailable() Then
6574             If SettingDialog.ReadPages > 0 Then
6575                 _waitTimeline = True
6576                 GetTimeline(WORKERTYPE.Timeline, 1, SettingDialog.ReadPages)
6577             End If
6578             If SettingDialog.ReadPagesReply > 0 Then
6579                 _waitReply = True
6580                 GetTimeline(WORKERTYPE.Reply, 1, SettingDialog.ReadPagesReply)
6581             End If
6582             If SettingDialog.ReadPagesDM > 0 Then
6583                 _waitDm = True
6584                 GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, SettingDialog.ReadPagesDM)
6585             End If
6586             If SettingDialog.GetFav Then
6587                 _waitFav = True
6588                 GetTimeline(WORKERTYPE.Favorites, 1, 1)
6589             End If
6590             Dim i As Integer = 0
6591             Do While (_waitTimeline OrElse _waitReply OrElse _waitDm OrElse _waitFav) AndAlso Not _endingFlag
6592                 System.Threading.Thread.Sleep(100)
6593                 My.Application.DoEvents()
6594                 i += 1
6595                 If i > 50 Then
6596                     If Not _endingFlag Then
6597                         _statuses.DistributePosts()
6598                         RefreshTimeline()
6599                     Else
6600                         Exit Sub
6601                     End If
6602                     i = 0
6603                 End If
6604             Loop
6605
6606             If _endingFlag Then Exit Sub
6607
6608             _statuses.DistributePosts()
6609             RefreshTimeline()
6610
6611             'バージョンチェック(引数:起動時チェックの場合はTrue・・・チェック結果のメッセージを表示しない)
6612             If SettingDialog.StartupVersion Then
6613                 CheckNewVersion(True)
6614             End If
6615
6616             ' Webモードで起動した場合に警告する
6617             If Not SettingDialog.StartupAPImodeNoWarning AndAlso Not SettingDialog.UseAPI Then
6618                 If MessageBox.Show(My.Resources.WebModeWarning1 + Environment.NewLine + My.Resources.WebModeWarning2 + Environment.NewLine + My.Resources.WebModeWarning3 + Environment.NewLine + My.Resources.WebModeWarning4, My.Resources.WebModeWarning5, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) = Windows.Forms.DialogResult.OK Then
6619                     SettingDialog.UseAPI = True
6620                     'SaveConfigsCommon()
6621                     MessageBox.Show(My.Resources.WebModeWarning6)
6622                 Else
6623                     MessageBox.Show(My.Resources.WebModeWarning7)
6624                     'MessageBox.Show("取得間隔に注意してください。タイムライン取得系APIはRecent,Reply,DMの合計で1時間に" + GetMaxCountApi.ToString() + "回までしか使えません。", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning)
6625                 End If
6626             End If
6627
6628         Else
6629             PostButton.Enabled = False
6630             FavAddToolStripMenuItem.Enabled = False
6631             FavRemoveToolStripMenuItem.Enabled = False
6632             MoveToHomeToolStripMenuItem.Enabled = False
6633             MoveToFavToolStripMenuItem.Enabled = False
6634             DeleteStripMenuItem.Enabled = False
6635             RefreshStripMenuItem.Enabled = False
6636         End If
6637         _initial = False
6638         If SettingDialog.TimelinePeriodInt > 0 Then TimerTimeline.Enabled = True
6639         If SettingDialog.DMPeriodInt > 0 Then TimerDM.Enabled = True
6640         If SettingDialog.ReplyPeriodInt > 0 Then TimerReply.Enabled = True
6641     End Sub
6642
6643     Private Sub doGetFollowersMenu(ByVal CacheInvalidate As Boolean)
6644         GetTimeline(WORKERTYPE.Follower, 1, 0)
6645         'Try
6646         '    StatusLabel.Text = My.Resources.UpdateFollowersMenuItem1_ClickText1
6647         '    My.Application.DoEvents()
6648         '    Me.Cursor = Cursors.WaitCursor
6649         '    Dim ret As String
6650         '    If SettingDialog.UseAPI Then
6651         '        ret = Twitter.GetFollowersApi()
6652         '    Else
6653         '        ret = Twitter.GetFollowers(CacheInvalidate)
6654         '    End If
6655         '    If ret <> "" Then
6656         '        StatusLabel.Text = My.Resources.UpdateFollowersMenuItem1_ClickText2 & ret
6657         '        Exit Sub
6658         '    End If
6659         '    StatusLabel.Text = My.Resources.UpdateFollowersMenuItem1_ClickText3
6660         'Finally
6661         '    Me.Cursor = Cursors.Default
6662         'End Try
6663     End Sub
6664
6665     Private Sub GetFollowersDiffToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GetFollowersDiffToolStripMenuItem.Click
6666         doGetFollowersMenu(False)       ' Followersリストキャッシュ有効
6667     End Sub
6668
6669     Private Sub GetFollowersAllToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GetFollowersAllToolStripMenuItem.Click
6670         doGetFollowersMenu(True)        ' Followersリストキャッシュ無効
6671     End Sub
6672
6673     Private Sub ReTweetStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReTweetStripMenuItem.Click
6674         'RT @id:内容
6675         If _curPost IsNot Nothing Then
6676             If _curPost.IsDm OrElse _
6677                Not StatusText.Enabled Then Exit Sub
6678
6679             If SettingDialog.ProtectNotInclude AndAlso _curPost.IsProtect Then
6680                 MessageBox.Show("Protected.")
6681                 Exit Sub
6682             End If
6683             Dim rtdata As String = _curPost.OriginalData
6684             rtdata = CreateRetweet(rtdata)
6685
6686             StatusText.Text = "RT @" + _curPost.Name + ": " + HttpUtility.HtmlDecode(rtdata)
6687
6688             StatusText.SelectionStart = 0
6689             StatusText.Focus()
6690         End If
6691     End Sub
6692
6693     Private Sub ReTweetOriginalStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReTweetOriginalStripMenuItem.Click
6694         '公式RT
6695         If _curPost IsNot Nothing AndAlso Not _curPost.IsDm Then
6696             If SettingDialog.ProtectNotInclude AndAlso _curPost.IsProtect Then
6697                 MessageBox.Show("Protected.")
6698                 Exit Sub
6699             End If
6700             If MessageBox.Show(My.Resources.RetweetQuestion1, "Retweet", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
6701                 Exit Sub
6702             End If
6703             Dim args As New GetWorkerArg
6704             args.ids = New List(Of Long)
6705             args.sIds = New List(Of Long)
6706             args.tName = _curTab.Text
6707             args.type = WORKERTYPE.Retweet
6708             args.ids.Add(_curPost.Id)
6709
6710             RunAsync(args)
6711         End If
6712
6713         ''RT @id:内容
6714         ''元発言のみRT
6715         'If _curPost IsNot Nothing Then
6716         '    If _curPost.IsDm OrElse _
6717         '       Not StatusText.Enabled Then Exit Sub
6718
6719         '    If SettingDialog.ProtectNotInclude AndAlso _curPost.IsProtect Then
6720         '        MessageBox.Show("Protected.")
6721         '        Exit Sub
6722         '    End If
6723
6724         '    Dim rtdata As String = _curPost.OriginalData
6725         '    rtdata = CreateRetweet(rtdata)
6726
6727         '    Dim rx As New Regex("^(?<multi>(RT @[0-9a-zA-Z_]+\s?:\s?)*)(?<org>RT @[0-9a-zA-Z_]+\s?:)")
6728         '    If rx.IsMatch(rtdata) Then
6729         '        StatusText.Text = HttpUtility.HtmlDecode(rx.Replace(rtdata, "${org}"))
6730         '    Else
6731         '        StatusText.Text = "RT @" + _curPost.Name + ": " + HttpUtility.HtmlDecode(rtdata)
6732         '    End If
6733
6734         '    StatusText.SelectionStart = 0
6735         '    StatusText.Focus()
6736         'End If
6737     End Sub
6738
6739     Private Function CreateRetweet(ByVal status As String) As String
6740
6741         ' Twitterにより省略されているURLを含むaタグをキャプチャしてリンク先URLへ置き換える
6742         '展開しないように変更
6743         '展開するか判定
6744         Dim isUrl As Boolean = False
6745         Dim rx As Regex = New Regex("<a target=""_self"" href=""(?<url>[^""]+)""[^>]*>(?<link>(https?|shttp|ftps?)://[^<]+)</a>")
6746         Dim ms As MatchCollection = rx.Matches(status)
6747         For Each m As Match In ms
6748             If m.Result("${link}").EndsWith("...") Then
6749                 isUrl = True
6750                 Exit For
6751             End If
6752         Next
6753         If isUrl Then
6754             status = rx.Replace(status, "${url}")
6755         Else
6756             status = rx.Replace(status, "${link}")
6757         End If
6758
6759         'その他のリンク(@IDなど)を置き換える
6760         rx = New Regex("@<a target=""_self"" href=""https?://twitter.com/(?<url>[^""]+)""[^>]*>(?<link>[^<]+)</a>")
6761         status = rx.Replace(status, "@${url}")
6762         'ハッシュタグ
6763         rx = New Regex("<a target=""_self"" href=""(?<url>[^""]+)""[^>]*>(?<link>[^<]+)</a>")
6764         status = rx.Replace(status, "${link}")
6765         '<br>タグ除去
6766         If StatusText.Multiline Then
6767             status = Regex.Replace(status, "(\r\n|\n|\r)?<br>", vbCrLf, RegexOptions.IgnoreCase Or RegexOptions.Multiline)
6768         Else
6769             status = Regex.Replace(status, "(\r\n|\n|\r)?<br>", "", RegexOptions.IgnoreCase Or RegexOptions.Multiline)
6770         End If
6771
6772         _reply_to_id = 0
6773         _reply_to_name = ""
6774
6775         Return status
6776     End Function
6777
6778     Private Sub DumpPostClassToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DumpPostClassToolStripMenuItem.Click
6779         If _curPost IsNot Nothing Then
6780             DispSelectedPost()
6781         End If
6782     End Sub
6783
6784     Private Sub MenuItemHelp_DropDownOpening(ByVal sender As Object, ByVal e As System.EventArgs) Handles MenuItemHelp.DropDownOpening
6785         If DebugBuild OrElse My.Computer.Keyboard.CapsLock AndAlso My.Computer.Keyboard.CtrlKeyDown AndAlso My.Computer.Keyboard.ShiftKeyDown Then
6786             DebugModeToolStripMenuItem.Visible = True
6787         Else
6788             DebugModeToolStripMenuItem.Visible = False
6789         End If
6790     End Sub
6791
6792     Private Sub ButtonPostMode_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonPostMode.Click
6793         ContextMenuStripPostMode.Show(ButtonPostMode, position:=New Point(0, ButtonPostMode.Height))
6794     End Sub
6795
6796     Private Sub ToolStripMenuItemUrlAutoShorten_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItemUrlAutoShorten.CheckedChanged
6797         SettingDialog.UrlConvertAuto = ToolStripMenuItemUrlAutoShorten.Checked
6798         'SaveConfigsCommon()
6799     End Sub
6800
6801     Private Sub ContextMenuStripPostMode_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStripPostMode.Opening
6802         ToolStripMenuItemUrlAutoShorten.Checked = SettingDialog.UrlConvertAuto
6803     End Sub
6804
6805     Private Sub TraceOutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TraceOutToolStripMenuItem.Click
6806         If TraceOutToolStripMenuItem.Checked Then
6807             TraceFlag = True
6808         Else
6809             TraceFlag = False
6810         End If
6811     End Sub
6812
6813     Private Sub TweenMain_Deactivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Deactivate
6814         '画面が非アクティブになったら、発言欄の背景色をデフォルトへ
6815         Me.StatusText_Leave(StatusText, System.EventArgs.Empty)
6816     End Sub
6817
6818     Private Sub TabRenameMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TabRenameMenuItem.Click
6819         If _rclickTabName = "" Then Exit Sub
6820         TabRename(_rclickTabName)
6821     End Sub
6822
6823     Private Sub UnuToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UnuToolStripMenuItem.Click
6824         UrlConvert(UrlConverter.Unu)
6825     End Sub
6826
6827     Private Sub BitlyToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BitlyToolStripMenuItem.Click
6828         UrlConvert(UrlConverter.Bitly)
6829     End Sub
6830
6831     Private Sub JmpToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles JmpStripMenuItem.Click
6832         UrlConvert(UrlConverter.Jmp)
6833     End Sub
6834
6835     Private Sub ApiInfoMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ApiInfoMenuItem.Click
6836         Dim info As New ApiInfo
6837         Dim tmp As String
6838
6839         If GetInfoApi(info) Then
6840             tmp = My.Resources.ApiInfo1 + info.MaxCount.ToString() + Environment.NewLine + _
6841                 My.Resources.ApiInfo2 + info.RemainCount.ToString + Environment.NewLine + _
6842                 My.Resources.ApiInfo3 + info.ResetTime.ToString()
6843         Else
6844             tmp = My.Resources.ApiInfo5
6845         End If
6846         MessageBox.Show(tmp, My.Resources.ApiInfo4, MessageBoxButtons.OK, MessageBoxIcon.Information)
6847     End Sub
6848
6849     Private Sub FollowCommandMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FollowCommandMenuItem.Click
6850         Dim id As String = ""
6851         If _curPost IsNot Nothing Then id = _curPost.Name
6852         FollowCommand(id)
6853     End Sub
6854
6855     Private Sub FollowCommand(ByVal id As String)
6856         Using inputName As New InputTabName()
6857             inputName.FormTitle = "Follow"
6858             inputName.FormDescription = My.Resources.FRMessage1
6859             inputName.TabName = id
6860             If inputName.ShowDialog() = Windows.Forms.DialogResult.OK AndAlso _
6861                Not String.IsNullOrEmpty(inputName.TabName.Trim()) Then
6862                 Dim ret As String = Twitter.PostFollowCommand(inputName.TabName.Trim())
6863                 If Not String.IsNullOrEmpty(ret) Then
6864                     MessageBox.Show(My.Resources.FRMessage2 + ret)
6865                 Else
6866                     MessageBox.Show(My.Resources.FRMessage3)
6867                 End If
6868             End If
6869             inputName.Dispose()
6870         End Using
6871     End Sub
6872
6873     Private Sub RemoveCommandMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RemoveCommandMenuItem.Click
6874         Dim id As String = ""
6875         If _curPost IsNot Nothing Then id = _curPost.Name
6876         RemoveCommand(id)
6877     End Sub
6878
6879     Private Sub RemoveCommand(ByVal id As String)
6880         Using inputName As New InputTabName()
6881             inputName.FormTitle = "Remove"
6882             inputName.FormDescription = My.Resources.FRMessage1
6883             inputName.TabName = id
6884             If inputName.ShowDialog() = Windows.Forms.DialogResult.OK AndAlso _
6885                Not String.IsNullOrEmpty(inputName.TabName.Trim()) Then
6886                 Dim ret As String = Twitter.PostRemoveCommand(inputName.TabName.Trim())
6887                 If Not String.IsNullOrEmpty(ret) Then
6888                     MessageBox.Show(My.Resources.FRMessage2 + ret)
6889                 Else
6890                     MessageBox.Show(My.Resources.FRMessage3)
6891                 End If
6892             End If
6893             inputName.Dispose()
6894         End Using
6895     End Sub
6896
6897     Private Sub FriendshipMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FriendshipMenuItem.Click
6898         Dim id As String = ""
6899         If _curPost IsNot Nothing Then
6900             id = _curPost.Name
6901         End If
6902         ShowFriendship(id)
6903     End Sub
6904
6905     Private Sub ShowFriendship(ByVal id As String)
6906         Using inputName As New InputTabName()
6907             inputName.FormTitle = "Show Friendships"
6908             inputName.FormDescription = My.Resources.FRMessage1
6909             inputName.TabName = id
6910             If inputName.ShowDialog() = Windows.Forms.DialogResult.OK AndAlso _
6911                Not String.IsNullOrEmpty(inputName.TabName.Trim()) Then
6912                 Dim ret As String = Twitter.GetFriendshipInfo(inputName.TabName.Trim())
6913                 MessageBox.Show(ret)
6914             End If
6915             inputName.Dispose()
6916         End Using
6917     End Sub
6918
6919     Private Sub OwnStatusMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OwnStatusMenuItem.Click
6920         Dim loc As String = ""
6921         Dim bio As String = ""
6922         If Not String.IsNullOrEmpty(Twitter.Location) Then
6923             loc = Twitter.Location
6924         End If
6925         If Not String.IsNullOrEmpty(Twitter.Bio) Then
6926             bio = Twitter.Bio
6927         End If
6928         MessageBox.Show("Following : " + Twitter.FriendsCount.ToString() + Environment.NewLine + _
6929                         "Followers : " + Twitter.FollowersCount.ToString() + Environment.NewLine + _
6930                         "Statuses count : " + Twitter.StatusesCount.ToString() + Environment.NewLine + _
6931                         "Location : " + loc + Environment.NewLine + _
6932                         "Bio : " + bio, "Your status")
6933     End Sub
6934
6935     Private Sub FollowContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FollowContextMenuItem.Click
6936         Dim m As Match = Regex.Match(PostBrowser.StatusText, "^https?://twitter.com/(?<name>[a-zA-Z0-9_]+)$")
6937         If m.Success Then
6938             FollowCommand(m.Result("${name}"))
6939         End If
6940     End Sub
6941
6942     Private Sub RemoveContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RemoveContextMenuItem.Click
6943         Dim m As Match = Regex.Match(PostBrowser.StatusText, "^https?://twitter.com/(?<name>[a-zA-Z0-9_]+)$")
6944         If m.Success Then
6945             RemoveCommand(m.Result("${name}"))
6946         End If
6947     End Sub
6948
6949     Private Sub FriendshipContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FriendshipContextMenuItem.Click
6950         Dim m As Match = Regex.Match(PostBrowser.StatusText, "^https?://twitter.com/(?<name>[a-zA-Z0-9_]+)$")
6951         If m.Success Then
6952             ShowFriendship(m.Result("${name}"))
6953         End If
6954     End Sub
6955
6956     Private Sub IdeographicSpaceToSpaceToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IdeographicSpaceToSpaceToolStripMenuItem.Click
6957         modifySettingCommon = True
6958     End Sub
6959
6960     'Private Sub UserPicture_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles UserPicture.Paint
6961     '    If e.Graphics.InterpolationMode <> Drawing2D.InterpolationMode.HighQualityBicubic Then
6962     '        e.Graphics.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
6963     '        UserPicture.GetType().GetMethod("OnPaint", BindingFlags.NonPublic Or BindingFlags.Instance).Invoke(UserPicture, New Object() {e})
6964     '    End If
6965     'End Sub
6966
6967     Private Sub QuoteStripMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles QuoteStripMenuItem.Click
6968         'QT @id:内容
6969         '返信先情報付加
6970         If _curPost IsNot Nothing Then
6971             If _curPost.IsDm OrElse _
6972                Not StatusText.Enabled Then Exit Sub
6973
6974             If SettingDialog.ProtectNotInclude AndAlso _curPost.IsProtect Then
6975                 MessageBox.Show("Protected.")
6976                 Exit Sub
6977             End If
6978             Dim rtdata As String = _curPost.OriginalData
6979             rtdata = CreateRetweet(rtdata)
6980
6981             StatusText.Text = " QT @" + _curPost.Name + ": " + HttpUtility.HtmlDecode(rtdata)
6982             _reply_to_id = _curPost.Id
6983             _reply_to_name = _curPost.Name
6984
6985             StatusText.SelectionStart = 0
6986             StatusText.Focus()
6987         End If
6988     End Sub
6989
6990 End Class