OSDN Git Service

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