OSDN Git Service

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