OSDN Git Service

UserTimelineタブでルールが追加できたりなんだり対応
[opentween/open-tween.git] / Tween / Tween.vb
1 ' Tween - Client of Twitter
2 ' Copyright (c) 2007-2011 kiri_feather (@kiri_feather) <kiri.feather@gmail.com>
3 '           (c) 2008-2011 Moz (@syo68k)
4 '           (c) 2008-2011 takeshik (@takeshik) <http://www.takeshik.org/>
5 '           (c) 2010-2011 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
6 '           (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
7 ' All rights reserved.
8
9 ' This file is part of Tween.
10
11 ' This program is free software; you can redistribute it and/or modify it
12 ' under the terms of the GNU General Public License as published by the Free
13 ' Software Foundation; either version 3 of the License, or (at your option)
14 ' any later version.
15
16 ' This program is distributed in the hope that it will be useful, but
17 ' WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 ' or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 ' for more details. 
20
21 ' You should have received a copy of the GNU General Public License along
22 ' with this program. If not, see <http://www.gnu.org/licenses/>, or write to
23 ' the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
24 ' Boston, MA 02110-1301, USA.
25
26 'コンパイル後コマンド
27 '"c:\Program Files\Microsoft.NET\SDK\v2.0\Bin\sgen.exe" /f /a:"$(TargetPath)"
28 '"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\sgen.exe" /f /a:"$(TargetPath)"
29
30
31 Imports System
32 Imports System.Text
33 Imports System.Text.RegularExpressions
34 Imports Tween.TweenCustomControl
35 Imports System.IO
36 Imports System.Web
37 Imports System.Reflection
38 Imports System.ComponentModel
39 Imports System.Diagnostics
40 Imports System.Threading
41 Imports System.Linq
42
43 Public Class TweenMain
44
45     '各種設定
46     Private _mySize As Size             '画面サイズ
47     Private _myLoc As Point             '画面位置
48     Private _mySpDis As Integer         '区切り位置
49     Private _mySpDis2 As Integer        '発言欄区切り位置
50     Private _mySpDis3 As Integer        'プレビュー区切り位置
51     Private _iconSz As Integer            'アイコンサイズ(現在は16、24、48の3種類。将来直接数字指定可能とする 注:24x24の場合に26と指定しているのはMSゴシック系フォントのための仕様)
52     Private _iconCol As Boolean           '1列表示の時True(48サイズのとき)
53
54     '雑多なフラグ類
55     Private _initial As Boolean         'True:起動時処理中
56     Private _initialLayout As Boolean = True
57     Private _ignoreConfigSave As Boolean         'True:起動時処理中
58     Private _tabDrag As Boolean           'タブドラッグ中フラグ(DoDragDropを実行するかの判定用)
59     Private _beforeSelectedTab As TabPage 'タブが削除されたときに前回選択されていたときのタブを選択する為に保持
60     Private _tabMouseDownPoint As Point
61     Private _rclickTabName As String      '右クリックしたタブの名前(Tabコントロール機能不足対応)
62     Private ReadOnly _syncObject As New Object()    'ロック用
63     Private Const detailHtmlFormatMono1 As String = "<html><head><style type=""text/css""><!-- pre {font-family: """
64     Private Const detailHtmlFormat2 As String = """, sans-serif; font-size: "
65     Private Const detailHtmlFormat3 As String = "pt; word-wrap: break-word; color:rgb("
66     Private Const detailHtmlFormat4 As String = ");} a:link, a:visited, a:active, a:hover {color:rgb("
67     Private Const detailHtmlFormat5 As String = "); } --></style></head><body style=""margin:0px; background-color:rgb("
68     Private Const detailHtmlFormatMono6 As String = ");""><pre>"
69     Private Const detailHtmlFormatMono7 As String = "</pre></body></html>"
70     Private Const detailHtmlFormat1 As String = "<html><head><style type=""text/css""><!-- p {font-family: """
71     Private Const detailHtmlFormat6 As String = ");""><p>"
72     Private Const detailHtmlFormat7 As String = "</p></body></html>"
73     Private detailHtmlFormatHeader As String
74     Private detailHtmlFormatFooter As String
75     Private _myStatusError As Boolean = False
76     Private _myStatusOnline As Boolean = False
77     Private soundfileListup As Boolean = False
78     Private _spaceKeyCanceler As SpaceKeyCanceler
79
80     '設定ファイル関連
81     'Private _cfg As SettingToConfig '旧
82     Private _cfgLocal As SettingLocal
83     Private _cfgCommon As SettingCommon
84     Private _modifySettingLocal As Boolean = False
85     Private _modifySettingCommon As Boolean = False
86     Private _modifySettingAtId As Boolean = False
87
88     'twitter解析部
89     Private tw As New Twitter
90
91     'サブ画面インスタンス
92     Private SettingDialog As AppendSettingDialog = AppendSettingDialog.Instance       '設定画面インスタンス
93     Private TabDialog As New TabsDialog        'タブ選択ダイアログインスタンス
94     Private SearchDialog As New SearchWord     '検索画面インスタンス
95     Private fltDialog As New FilterDialog 'フィルター編集画面
96     Private UrlDialog As New OpenURL
97     Private dialogAsShieldicon As DialogAsShieldIcon    ' シールドアイコン付きダイアログ
98     Public AtIdSupl As AtIdSupplement    '@id補助
99     Public HashSupl As AtIdSupplement    'Hashtag補助
100     Public HashMgr As HashtagManage
101     Private evtDialog As EventViewerDialog
102
103     '表示フォント、色、アイコン
104     Private _fntUnread As Font            '未読用フォント
105     Private _clUnread As Color            '未読用文字色
106     Private _fntReaded As Font            '既読用フォント
107     Private _clReaded As Color            '既読用文字色
108     Private _clFav As Color               'Fav用文字色
109     Private _clOWL As Color               '片思い用文字色
110     Private _clRetweet As Color               'Retweet用文字色
111     Private _fntDetail As Font            '発言詳細部用フォント
112     Private _clDetail As Color              '発言詳細部用色
113     Private _clDetailLink As Color          '発言詳細部用リンク文字色
114     Private _clDetailBackcolor As Color     '発言詳細部用背景色
115     Private _clSelf As Color              '自分の発言用背景色
116     Private _clAtSelf As Color            '自分宛返信用背景色
117     Private _clTarget As Color            '選択発言者の他の発言用背景色
118     Private _clAtTarget As Color          '選択発言中の返信先用背景色
119     Private _clAtFromTarget As Color      '選択発言者への返信発言用背景色
120     Private _clAtTo As Color              '選択発言の唯一@先
121     Private _clListBackcolor As Color       'リスト部通常発言背景色
122     Private _clInputBackcolor As Color      '入力欄背景色
123     Private _clInputFont As Color           '入力欄文字色
124     Private _fntInputFont As Font           '入力欄フォント
125     Private TIconDic As IDictionary(Of String, Image)        'アイコン画像リスト
126     Private NIconAt As Icon               'At.ico             タスクトレイアイコン:通常時
127     Private NIconAtRed As Icon            'AtRed.ico          タスクトレイアイコン:通信エラー時
128     Private NIconAtSmoke As Icon          'AtSmoke.ico        タスクトレイアイコン:オフライン時
129     Private NIconRefresh(3) As Icon       'Refresh.ico        タスクトレイアイコン:更新中(アニメーション用に4種類を保持するリスト)
130     Private TabIcon As Icon               'Tab.ico            未読のあるタブ用アイコン
131     Private MainIcon As Icon              'Main.ico           画面左上のアイコン
132     Private ReplyIcon As Icon               '5g
133     Private ReplyIconBlink As Icon          '6g
134
135     Private _anchorPost As PostClass
136     Private _anchorFlag As Boolean        'True:関連発言移動中(関連移動以外のオペレーションをするとFalseへ。Trueだとリスト背景色をアンカー発言選択中として描画)
137
138     Private _history As New List(Of PostingStatus)   '発言履歴
139     Private _hisIdx As Integer                  '発言履歴カレントインデックス
140
141     '発言投稿時のAPI引数(発言編集時に設定。手書きreplyでは設定されない)
142     Private _reply_to_id As Long     ' リプライ先のステータスID 0の場合はリプライではない 注:複数あてのものはリプライではない
143     Private _reply_to_name As String    ' リプライ先ステータスの書き込み者の名前
144
145     '時速表示用
146     Private _postTimestamps As New List(Of Date)
147     Private _favTimestamps As New List(Of Date)
148     Private _tlTimestamps As New Dictionary(Of Date, Integer)
149     Private _tlCount As Integer
150
151     ' 以下DrawItem関連
152     Private _brsHighLight As New SolidBrush(Color.FromKnownColor(KnownColor.Highlight))
153     Private _brsHighLightText As New SolidBrush(Color.FromKnownColor(KnownColor.HighlightText))
154     Private _brsForeColorUnread As SolidBrush
155     Private _brsForeColorReaded As SolidBrush
156     Private _brsForeColorFav As SolidBrush
157     Private _brsForeColorOWL As SolidBrush
158     Private _brsForeColorRetweet As SolidBrush
159     Private _brsBackColorMine As SolidBrush
160     Private _brsBackColorAt As SolidBrush
161     Private _brsBackColorYou As SolidBrush
162     Private _brsBackColorAtYou As SolidBrush
163     Private _brsBackColorAtFromTarget As SolidBrush
164     Private _brsBackColorAtTo As SolidBrush
165     Private _brsBackColorNone As SolidBrush
166     Private _brsDeactiveSelection As New SolidBrush(Color.FromKnownColor(KnownColor.ButtonFace)) 'Listにフォーカスないときの選択行の背景色
167     Private sfTab As New StringFormat()
168
169     '''''''''''''''''''''''''''''''''''''''''''''''''''''
170     Private _apiGauge As New ToolStripAPIGauge()
171     Private _statuses As TabInformations
172     Private _itemCache() As ListViewItem
173     Private _itemCacheIndex As Integer
174     Private _postCache() As PostClass
175     Private _curTab As TabPage
176     Private _curItemIndex As Integer
177     Private _curList As DetailsListView
178     Private _curPost As PostClass
179     Private _isColumnChanged As Boolean = False
180     Private _waitTimeline As Boolean = False
181     Private _waitReply As Boolean = False
182     Private _waitDm As Boolean = False
183     Private _waitFav As Boolean = False
184     Private _waitPubSearch As Boolean = False
185     Private _waitUserTimeline As Boolean = False
186     Private _waitLists As Boolean = False
187     Private _bw(18) As BackgroundWorker
188     Private _bwFollower As BackgroundWorker
189     Private cMode As Integer
190     Private shield As New ShieldIcon
191     Private SecurityManager As InternetSecurityManager
192     Private Thumbnail As Thumbnail
193
194     Private UnreadCounter As Integer = -1
195     Private UnreadAtCounter As Integer = -1
196
197     Private ColumnOrgText(8) As String
198     Private ColumnText(8) As String
199
200     Private _DoFavRetweetFlags As Boolean = False
201     Private osResumed As Boolean = False
202     Private pictureService As Dictionary(Of String, IMultimediaShareService)
203
204     '''''''''''''''''''''''''''''''''''''''''''''''''''''
205     Private _postBrowserStatusText As String = ""
206
207     Private _colorize As Boolean = False
208
209     Private WithEvents TimerTimeline As New System.Timers.Timer
210
211     Private WithEvents displayItem As ImageListViewItem
212
213     'URL短縮のUndo用
214     Private Structure urlUndo
215         Public Before As String
216         Public After As String
217     End Structure
218
219     Private urlUndoBuffer As Generic.List(Of urlUndo) = Nothing
220
221     Private Structure ReplyChain
222         Public OriginalId As Long
223         Public InReplyToId As Long
224         Public OriginalTab As TabPage
225
226         Sub New(ByVal originalId As Long, ByVal inReplyToId As Long, ByVal originalTab As TabPage)
227             Me.OriginalId = originalId
228             Me.InReplyToId = inReplyToId
229             Me.OriginalTab = originalTab
230         End Sub
231     End Structure
232
233     Private replyChains As Stack(Of ReplyChain)
234
235     'Backgroundworkerの処理結果通知用引数構造体
236     Private Class GetWorkerResult
237         Public retMsg As String = ""                     '処理結果詳細メッセージ。エラー時に値がセットされる
238         Public page As Integer                      '取得対象ページ番号
239         Public endPage As Integer                   '取得終了ページ番号(継続可能ならインクリメントされて返る。pageと比較して継続判定)
240         Public type As WORKERTYPE                   '処理種別
241         Public imgs As Dictionary(Of String, Image)                    '新規取得したアイコンイメージ
242         Public tName As String = ""                  'Fav追加・削除時のタブ名
243         Public ids As List(Of Long)               'Fav追加・削除時のID
244         Public sIds As List(Of Long)                  'Fav追加・削除成功分のID
245         Public newDM As Boolean
246         Public addCount As Integer
247         Public status As PostingStatus
248     End Class
249
250     'Backgroundworkerへ処理内容を通知するための引数用構造体
251     Private Class GetWorkerArg
252         Public page As Integer                      '処理対象ページ番号
253         Public endPage As Integer                   '処理終了ページ番号(起動時の読み込みページ数。通常時はpageと同じ値をセット)
254         Public type As WORKERTYPE                   '処理種別
255         Public url As String = ""            'URLをブラウザで開くときのアドレス
256         Public status As New PostingStatus          '発言POST時の発言内容
257         Public ids As List(Of Long)               'Fav追加・削除時のItemIndex
258         Public sIds As List(Of Long)              'Fav追加・削除成功分のItemIndex
259         Public tName As String = ""            'Fav追加・削除時のタブ名
260     End Class
261
262     '検索処理タイプ
263     Private Enum SEARCHTYPE
264         DialogSearch
265         NextSearch
266         PrevSearch
267     End Enum
268
269     Private Class PostingStatus
270         Public status As String = ""
271         Public inReplyToId As Long = 0
272         Public inReplyToName As String = ""
273         Public imageService As String = ""      '画像投稿サービス名
274         Public imagePath As String = ""
275         Public Sub New()
276
277         End Sub
278         Public Sub New(ByVal status As String, ByVal replyToId As Long, ByVal replyToName As String)
279             Me.status = status
280             Me.inReplyToId = replyToId
281             Me.inReplyToName = replyToName
282         End Sub
283     End Class
284
285     Private Class SpaceKeyCanceler
286         Inherits NativeWindow
287         Implements IDisposable
288
289         Dim WM_KEYDOWN As Integer = &H100
290         Dim VK_SPACE As Integer = &H20
291
292         Public Sub New(ByVal control As Control)
293             Me.AssignHandle(control.Handle)
294         End Sub
295
296         Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
297             If (m.Msg = WM_KEYDOWN) AndAlso (CInt(m.WParam) = VK_SPACE) Then
298                 RaiseEvent SpaceCancel(Me, EventArgs.Empty)
299                 Exit Sub
300             End If
301
302             MyBase.WndProc(m)
303         End Sub
304
305         Public Event SpaceCancel As EventHandler
306
307         Public Sub Dispose() Implements IDisposable.Dispose
308             Me.ReleaseHandle()
309         End Sub
310     End Class
311
312     Private Sub TweenMain_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
313         '画面がアクティブになったら、発言欄の背景色戻す
314         If StatusText.Focused Then
315             Me.StatusText_Enter(Me.StatusText, System.EventArgs.Empty)
316         End If
317     End Sub
318
319     Private Sub TweenMain_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
320         '後始末
321         SettingDialog.Dispose()
322         TabDialog.Dispose()
323         SearchDialog.Dispose()
324         fltDialog.Dispose()
325         UrlDialog.Dispose()
326         _spaceKeyCanceler.Dispose()
327         If NIconAt IsNot Nothing Then NIconAt.Dispose()
328         If NIconAtRed IsNot Nothing Then NIconAtRed.Dispose()
329         If NIconAtSmoke IsNot Nothing Then NIconAtSmoke.Dispose()
330         If NIconRefresh(0) IsNot Nothing Then NIconRefresh(0).Dispose()
331         If NIconRefresh(1) IsNot Nothing Then NIconRefresh(1).Dispose()
332         If NIconRefresh(2) IsNot Nothing Then NIconRefresh(2).Dispose()
333         If NIconRefresh(3) IsNot Nothing Then NIconRefresh(3).Dispose()
334         If TabIcon IsNot Nothing Then TabIcon.Dispose()
335         If MainIcon IsNot Nothing Then MainIcon.Dispose()
336         If ReplyIcon IsNot Nothing Then ReplyIcon.Dispose()
337         If ReplyIconBlink IsNot Nothing Then ReplyIconBlink.Dispose()
338         _brsHighLight.Dispose()
339         _brsHighLightText.Dispose()
340         If _brsForeColorUnread IsNot Nothing Then _brsForeColorUnread.Dispose()
341         If _brsForeColorReaded IsNot Nothing Then _brsForeColorReaded.Dispose()
342         If _brsForeColorFav IsNot Nothing Then _brsForeColorFav.Dispose()
343         If _brsForeColorOWL IsNot Nothing Then _brsForeColorOWL.Dispose()
344         If _brsForeColorRetweet IsNot Nothing Then _brsForeColorRetweet.Dispose()
345         If _brsBackColorMine IsNot Nothing Then _brsBackColorMine.Dispose()
346         If _brsBackColorAt IsNot Nothing Then _brsBackColorAt.Dispose()
347         If _brsBackColorYou IsNot Nothing Then _brsBackColorYou.Dispose()
348         If _brsBackColorAtYou IsNot Nothing Then _brsBackColorAtYou.Dispose()
349         If _brsBackColorAtFromTarget IsNot Nothing Then _brsBackColorAtFromTarget.Dispose()
350         If _brsBackColorAtTo IsNot Nothing Then _brsBackColorAtTo.Dispose()
351         If _brsBackColorNone IsNot Nothing Then _brsBackColorNone.Dispose()
352         If _brsDeactiveSelection IsNot Nothing Then _brsDeactiveSelection.Dispose()
353         shield.Dispose()
354         'sf.Dispose()
355         sfTab.Dispose()
356         For Each bw As BackgroundWorker In _bw
357             If bw IsNot Nothing Then
358                 bw.Dispose()
359             End If
360         Next
361         If _bwFollower IsNot Nothing Then
362             _bwFollower.Dispose()
363         End If
364         Me._apiGauge.Dispose()
365         If TIconDic IsNot Nothing Then
366             DirectCast(Me.TIconDic, ImageDictionary).PauseGetImage = True
367             DirectCast(TIconDic, IDisposable).Dispose()
368         End If
369         ' 終了時にRemoveHandlerしておかないとメモリリークする
370         ' http://msdn.microsoft.com/ja-jp/library/microsoft.win32.systemevents.powermodechanged.aspx
371         RemoveHandler Microsoft.Win32.SystemEvents.PowerModeChanged, AddressOf SystemEvents_PowerModeChanged
372     End Sub
373
374     Private Sub LoadIcon(ByRef IconInstance As Icon, ByVal FileName As String)
375         Dim dir As String = Application.StartupPath
376         If File.Exists(Path.Combine(dir, FileName)) Then
377             Try
378                 IconInstance = New Icon(Path.Combine(dir, FileName))
379             Catch ex As Exception
380             End Try
381         End If
382     End Sub
383
384     Private Sub LoadIcons()
385         '着せ替えアイコン対応
386         'タスクトレイ通常時アイコン
387         Dim dir As String = Application.StartupPath
388
389         NIconAt = My.Resources.At
390         NIconAtRed = My.Resources.AtRed
391         NIconAtSmoke = My.Resources.AtSmoke
392         NIconRefresh(0) = My.Resources.Refresh
393         NIconRefresh(1) = My.Resources.Refresh2
394         NIconRefresh(2) = My.Resources.Refresh3
395         NIconRefresh(3) = My.Resources.Refresh4
396         TabIcon = My.Resources.TabIcon
397         MainIcon = My.Resources.MIcon
398         ReplyIcon = My.Resources.Reply
399         ReplyIconBlink = My.Resources.ReplyBlink
400
401         If Not Directory.Exists(Path.Combine(dir, "Icons")) Then
402             Exit Sub
403         End If
404
405         LoadIcon(NIconAt, "Icons\At.ico")
406
407         'タスクトレイエラー時アイコン
408         LoadIcon(NIconAtRed, "Icons\AtRed.ico")
409
410         'タスクトレイオフライン時アイコン
411         LoadIcon(NIconAtSmoke, "Icons\AtSmoke.ico")
412
413         'タスクトレイ更新中アイコン
414         'アニメーション対応により4種類読み込み
415         LoadIcon(NIconRefresh(0), "Icons\Refresh.ico")
416         LoadIcon(NIconRefresh(1), "Icons\Refresh2.ico")
417         LoadIcon(NIconRefresh(2), "Icons\Refresh3.ico")
418         LoadIcon(NIconRefresh(3), "Icons\Refresh4.ico")
419
420         'タブ見出し未読表示アイコン
421         LoadIcon(TabIcon, "Icons\Tab.ico")
422
423         '画面のアイコン
424         LoadIcon(MainIcon, "Icons\MIcon.ico")
425
426         'Replyのアイコン
427         LoadIcon(ReplyIcon, "Icons\Reply.ico")
428
429         'Reply点滅のアイコン
430         LoadIcon(ReplyIconBlink, "Icons\ReplyBlink.ico")
431     End Sub
432
433     Private Sub InitColumnText()
434
435         ColumnText(0) = ""
436         ColumnText(1) = My.Resources.AddNewTabText2
437         ColumnText(2) = My.Resources.AddNewTabText3
438         ColumnText(3) = My.Resources.AddNewTabText4_2
439         ColumnText(4) = My.Resources.AddNewTabText5
440         ColumnText(5) = ""
441         ColumnText(6) = ""
442         ColumnText(7) = "Source"
443
444         ColumnOrgText(0) = ""
445         ColumnOrgText(1) = My.Resources.AddNewTabText2
446         ColumnOrgText(2) = My.Resources.AddNewTabText3
447         ColumnOrgText(3) = My.Resources.AddNewTabText4_2
448         ColumnOrgText(4) = My.Resources.AddNewTabText5
449         ColumnOrgText(5) = ""
450         ColumnOrgText(6) = ""
451         ColumnOrgText(7) = "Source"
452
453         Dim c As Integer = 0
454         Select Case _statuses.SortMode
455             Case IdComparerClass.ComparerMode.Nickname  'ニックネーム
456                 c = 1
457             Case IdComparerClass.ComparerMode.Data  '本文
458                 c = 2
459             Case IdComparerClass.ComparerMode.Id  '時刻=発言Id
460                 c = 3
461             Case IdComparerClass.ComparerMode.Name  '名前
462                 c = 4
463             Case IdComparerClass.ComparerMode.Source  'Source
464                 c = 7
465         End Select
466
467         If _iconCol Then
468             If _statuses.SortOrder() = SortOrder.Descending Then
469                 ' U+25BE BLACK DOWN-POINTING SMALL TRIANGLE
470                 ColumnText(2) = ColumnOrgText(2) + "▾"
471             Else
472                 ' U+25B4 BLACK UP-POINTING SMALL TRIANGLE
473                 ColumnText(2) = ColumnOrgText(2) + "▴"
474             End If
475         Else
476             If _statuses.SortOrder() = SortOrder.Descending Then
477                 ' U+25BE BLACK DOWN-POINTING SMALL TRIANGLE
478                 ColumnText(c) = ColumnOrgText(c) + "▾"
479             Else
480                 ' U+25B4 BLACK UP-POINTING SMALL TRIANGLE
481                 ColumnText(c) = ColumnOrgText(c) + "▴"
482             End If
483         End If
484     End Sub
485
486     Private Sub InitializeTraceFrag()
487 #If DEBUG Then
488         TraceOutToolStripMenuItem.Checked = True
489         TraceFlag = True
490 #End If
491         If Not fileVersion.EndsWith("0") Then
492             TraceOutToolStripMenuItem.Checked = True
493             TraceFlag = True
494         End If
495     End Sub
496
497     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
498         _ignoreConfigSave = True
499         Me.Visible = False
500         SecurityManager = New InternetSecurityManager(PostBrowser)
501         Thumbnail = New Thumbnail(Me)
502
503         AddHandler TwitterApiInfo.Changed, AddressOf SetStatusLabelApiHandler
504         AddHandler Microsoft.Win32.SystemEvents.PowerModeChanged, AddressOf SystemEvents_PowerModeChanged
505
506         VerUpMenuItem.Image = shield.Icon
507         If Not My.Application.CommandLineArgs.Count = 0 AndAlso My.Application.CommandLineArgs.Contains("/d") Then TraceFlag = True
508
509         Me._spaceKeyCanceler = New SpaceKeyCanceler(Me.PostButton)
510         AddHandler Me._spaceKeyCanceler.SpaceCancel, AddressOf spaceKeyCanceler_SpaceCancel
511
512         Regex.CacheSize = 100
513
514         fileVersion = DirectCast(Assembly.GetExecutingAssembly().GetCustomAttributes(GetType(AssemblyFileVersionAttribute), False)(0), AssemblyFileVersionAttribute).Version
515         InitializeTraceFrag()
516         LoadIcons() ' アイコン読み込み
517
518         '発言保持クラス
519         _statuses = TabInformations.GetInstance()
520
521         'アイコン設定
522         Me.Icon = MainIcon              'メインフォーム(TweenMain)
523         NotifyIcon1.Icon = NIconAt      'タスクトレイ
524         TabImage.Images.Add(TabIcon)    'タブ見出し
525
526         SettingDialog.Owner = Me
527         SearchDialog.Owner = Me
528         fltDialog.Owner = Me
529         TabDialog.Owner = Me
530         UrlDialog.Owner = Me
531
532         _history.Add(New PostingStatus)
533         _hisIdx = 0
534         _reply_to_id = 0
535         _reply_to_name = ""
536
537         '<<<<<<<<<設定関連>>>>>>>>>
538         '設定コンバージョン
539         'ConvertConfig()
540
541         ''設定読み出し
542         LoadConfig()
543
544         '新着バルーン通知のチェック状態設定
545         NewPostPopMenuItem.Checked = _cfgCommon.NewAllPop
546         Me.NotifyFileMenuItem.Checked = NewPostPopMenuItem.Checked
547
548         'フォント&文字色&背景色保持
549         _fntUnread = _cfgLocal.FontUnread
550         _clUnread = _cfgLocal.ColorUnread
551         _fntReaded = _cfgLocal.FontRead
552         _clReaded = _cfgLocal.ColorRead
553         _clFav = _cfgLocal.ColorFav
554         _clOWL = _cfgLocal.ColorOWL
555         _clRetweet = _cfgLocal.ColorRetweet
556         _fntDetail = _cfgLocal.FontDetail
557         _clDetail = _cfgLocal.ColorDetail
558         _clDetailLink = _cfgLocal.ColorDetailLink
559         _clDetailBackcolor = _cfgLocal.ColorDetailBackcolor
560         _clSelf = _cfgLocal.ColorSelf
561         _clAtSelf = _cfgLocal.ColorAtSelf
562         _clTarget = _cfgLocal.ColorTarget
563         _clAtTarget = _cfgLocal.ColorAtTarget
564         _clAtFromTarget = _cfgLocal.ColorAtFromTarget
565         _clAtTo = _cfgLocal.ColorAtTo
566         _clListBackcolor = _cfgLocal.ColorListBackcolor
567         _clInputBackcolor = _cfgLocal.ColorInputBackcolor
568         _clInputFont = _cfgLocal.ColorInputFont
569         _fntInputFont = _cfgLocal.FontInputFont
570
571         _brsForeColorUnread = New SolidBrush(_clUnread)
572         _brsForeColorReaded = New SolidBrush(_clReaded)
573         _brsForeColorFav = New SolidBrush(_clFav)
574         _brsForeColorOWL = New SolidBrush(_clOWL)
575         _brsForeColorRetweet = New SolidBrush(_clRetweet)
576         _brsBackColorMine = New SolidBrush(_clSelf)
577         _brsBackColorAt = New SolidBrush(_clAtSelf)
578         _brsBackColorYou = New SolidBrush(_clTarget)
579         _brsBackColorAtYou = New SolidBrush(_clAtTarget)
580         _brsBackColorAtFromTarget = New SolidBrush(_clAtFromTarget)
581         _brsBackColorAtTo = New SolidBrush(_clAtTo)
582         '_brsBackColorNone = New SolidBrush(Color.FromKnownColor(KnownColor.Window))
583         _brsBackColorNone = New SolidBrush(_clListBackcolor)
584
585         ' StringFormatオブジェクトへの事前設定
586         'sf.Alignment = StringAlignment.Near             ' Textを近くへ配置(左から右の場合は左寄せ)
587         'sf.LineAlignment = StringAlignment.Near         ' Textを近くへ配置(上寄せ)
588         'sf.FormatFlags = StringFormatFlags.LineLimit    ' 
589         sfTab.Alignment = StringAlignment.Center
590         sfTab.LineAlignment = StringAlignment.Center
591
592         '設定画面への反映
593         SettingDialog.IsOAuth = _cfgCommon.IsOAuth
594         HttpTwitter.TwitterUrl = _cfgCommon.TwitterUrl
595         HttpTwitter.TwitterSearchUrl = _cfgCommon.TwitterSearchUrl
596         SettingDialog.TwitterApiUrl = _cfgCommon.TwitterUrl
597         SettingDialog.TwitterSearchApiUrl = _cfgCommon.TwitterSearchUrl
598         '認証関連
599         If _cfgCommon.IsOAuth Then
600             If _cfgCommon.Token = "" Then _cfgCommon.UserName = ""
601             tw.Initialize(_cfgCommon.Token, _cfgCommon.TokenSecret, _cfgCommon.UserName)
602         Else
603             tw.Initialize(_cfgCommon.UserName, _cfgCommon.Password)
604         End If
605
606         SettingDialog.TimelinePeriodInt = _cfgCommon.TimelinePeriod
607         SettingDialog.ReplyPeriodInt = _cfgCommon.ReplyPeriod
608         SettingDialog.DMPeriodInt = _cfgCommon.DMPeriod
609         SettingDialog.PubSearchPeriodInt = _cfgCommon.PubSearchPeriod
610         SettingDialog.UserTimelinePeriodInt = _cfgCommon.UserTimelinePeriod
611         SettingDialog.ListsPeriodInt = _cfgCommon.ListsPeriod
612         '不正値チェック
613         If Not My.Application.CommandLineArgs.Contains("nolimit") Then
614             If SettingDialog.TimelinePeriodInt < 15 AndAlso SettingDialog.TimelinePeriodInt > 0 Then SettingDialog.TimelinePeriodInt = 15
615             If SettingDialog.ReplyPeriodInt < 15 AndAlso SettingDialog.ReplyPeriodInt > 0 Then SettingDialog.ReplyPeriodInt = 15
616             If SettingDialog.DMPeriodInt < 15 AndAlso SettingDialog.DMPeriodInt > 0 Then SettingDialog.DMPeriodInt = 15
617             If SettingDialog.PubSearchPeriodInt < 30 AndAlso SettingDialog.PubSearchPeriodInt > 0 Then SettingDialog.PubSearchPeriodInt = 30
618             If SettingDialog.UserTimelinePeriodInt < 15 AndAlso SettingDialog.UserTimelinePeriodInt > 0 Then SettingDialog.UserTimelinePeriodInt = 15
619             If SettingDialog.ListsPeriodInt < 15 AndAlso SettingDialog.ListsPeriodInt > 0 Then SettingDialog.ListsPeriodInt = 15
620         End If
621
622         '起動時読み込み分を既読にするか。Trueなら既読として処理
623         SettingDialog.Readed = _cfgCommon.Read
624         '新着取得時のリストスクロールをするか。Trueならスクロールしない
625         ListLockMenuItem.Checked = _cfgCommon.ListLock
626         Me.LockListFileMenuItem.Checked = _cfgCommon.ListLock
627         SettingDialog.IconSz = _cfgCommon.IconSize
628         '文末ステータス
629         SettingDialog.Status = _cfgLocal.StatusText
630         '未読管理。Trueなら未読管理する
631         SettingDialog.UnreadManage = _cfgCommon.UnreadManage
632         'サウンド再生(タブ別設定より優先)
633         SettingDialog.PlaySound = _cfgCommon.PlaySound
634         PlaySoundMenuItem.Checked = SettingDialog.PlaySound
635         Me.PlaySoundFileMenuItem.Checked = SettingDialog.PlaySound
636         '片思い表示。Trueなら片思い表示する
637         SettingDialog.OneWayLove = _cfgCommon.OneWayLove
638         'フォント&文字色&背景色
639         SettingDialog.FontUnread = _fntUnread
640         SettingDialog.ColorUnread = _clUnread
641         SettingDialog.FontReaded = _fntReaded
642         SettingDialog.ColorReaded = _clReaded
643         SettingDialog.ColorFav = _clFav
644         SettingDialog.ColorOWL = _clOWL
645         SettingDialog.ColorRetweet = _clRetweet
646         SettingDialog.FontDetail = _fntDetail
647         SettingDialog.ColorDetail = _clDetail
648         SettingDialog.ColorDetailLink = _clDetailLink
649         SettingDialog.ColorDetailBackcolor = _clDetailBackcolor
650         SettingDialog.ColorSelf = _clSelf
651         SettingDialog.ColorAtSelf = _clAtSelf
652         SettingDialog.ColorTarget = _clTarget
653         SettingDialog.ColorAtTarget = _clAtTarget
654         SettingDialog.ColorAtFromTarget = _clAtFromTarget
655         SettingDialog.ColorAtTo = _clAtTo
656         SettingDialog.ColorListBackcolor = _clListBackcolor
657         SettingDialog.ColorInputBackcolor = _clInputBackcolor
658         SettingDialog.ColorInputFont = _clInputFont
659         SettingDialog.FontInputFont = _fntInputFont
660
661         SettingDialog.NameBalloon = _cfgCommon.NameBalloon
662         SettingDialog.PostCtrlEnter = _cfgCommon.PostCtrlEnter
663         SettingDialog.PostShiftEnter = _cfgCommon.PostShiftEnter
664
665         SettingDialog.CountApi = _cfgCommon.CountApi
666         SettingDialog.CountApiReply = _cfgCommon.CountApiReply
667         If SettingDialog.CountApi < 20 OrElse SettingDialog.CountApi > 200 Then SettingDialog.CountApi = 60
668         If SettingDialog.CountApiReply < 20 OrElse SettingDialog.CountApiReply > 200 Then SettingDialog.CountApiReply = 40
669
670         SettingDialog.BrowserPath = _cfgLocal.BrowserPath
671         SettingDialog.PostAndGet = _cfgCommon.PostAndGet
672         SettingDialog.UseRecommendStatus = _cfgLocal.UseRecommendStatus
673         SettingDialog.DispUsername = _cfgCommon.DispUsername
674         SettingDialog.CloseToExit = _cfgCommon.CloseToExit
675         SettingDialog.MinimizeToTray = _cfgCommon.MinimizeToTray
676         SettingDialog.DispLatestPost = _cfgCommon.DispLatestPost
677         SettingDialog.SortOrderLock = _cfgCommon.SortOrderLock
678         SettingDialog.TinyUrlResolve = _cfgCommon.TinyUrlResolve
679
680         SettingDialog.SelectedProxyType = _cfgLocal.ProxyType
681         SettingDialog.ProxyAddress = _cfgLocal.ProxyAddress
682         SettingDialog.ProxyPort = _cfgLocal.ProxyPort
683         SettingDialog.ProxyUser = _cfgLocal.ProxyUser
684         SettingDialog.ProxyPassword = _cfgLocal.ProxyPassword
685
686         SettingDialog.PeriodAdjust = _cfgCommon.PeriodAdjust
687         SettingDialog.StartupVersion = _cfgCommon.StartupVersion
688         SettingDialog.StartupFollowers = _cfgCommon.StartupFollowers
689         SettingDialog.RestrictFavCheck = _cfgCommon.RestrictFavCheck
690         SettingDialog.AlwaysTop = _cfgCommon.AlwaysTop
691         SettingDialog.UrlConvertAuto = _cfgCommon.UrlConvertAuto
692
693         SettingDialog.OutputzEnabled = _cfgCommon.Outputz
694         SettingDialog.OutputzKey = _cfgCommon.OutputzKey
695         SettingDialog.OutputzUrlmode = _cfgCommon.OutputzUrlMode
696
697         SettingDialog.UseUnreadStyle = _cfgCommon.UseUnreadStyle
698         SettingDialog.DefaultTimeOut = _cfgCommon.DefaultTimeOut
699         SettingDialog.RetweetNoConfirm = _cfgCommon.RetweetNoConfirm
700         SettingDialog.PlaySound = _cfgCommon.PlaySound
701         SettingDialog.DateTimeFormat = _cfgCommon.DateTimeFormat
702         SettingDialog.LimitBalloon = _cfgCommon.LimitBalloon
703         SettingDialog.EventNotifyEnabled = _cfgCommon.EventNotifyEnabled
704         SettingDialog.EventNotifyFlag = _cfgCommon.EventNotifyFlag
705         SettingDialog.IsMyEventNotifyFlag = _cfgCommon.IsMyEventNotifyFlag
706         SettingDialog.ForceEventNotify = _cfgCommon.ForceEventNotify
707         SettingDialog.FavEventUnread = _cfgCommon.FavEventUnread
708         SettingDialog.TranslateLanguage = _cfgCommon.TranslateLanguage
709         SettingDialog.EventSoundFile = _cfgCommon.EventSoundFile
710
711         '廃止サービスが選択されていた場合bit.lyへ読み替え
712         If _cfgCommon.AutoShortUrlFirst < 0 Then
713             _cfgCommon.AutoShortUrlFirst = Tween.UrlConverter.Bitly
714         End If
715
716         SettingDialog.AutoShortUrlFirst = _cfgCommon.AutoShortUrlFirst
717         SettingDialog.TabIconDisp = _cfgCommon.TabIconDisp
718         SettingDialog.ReplyIconState = _cfgCommon.ReplyIconState
719         SettingDialog.ReadOwnPost = _cfgCommon.ReadOwnPost
720         SettingDialog.GetFav = _cfgCommon.GetFav
721         SettingDialog.ReadOldPosts = _cfgCommon.ReadOldPosts
722         SettingDialog.UseSsl = _cfgCommon.UseSsl
723         SettingDialog.BitlyUser = _cfgCommon.BilyUser
724         SettingDialog.BitlyPwd = _cfgCommon.BitlyPwd
725         SettingDialog.ShowGrid = _cfgCommon.ShowGrid
726         SettingDialog.Language = _cfgCommon.Language
727         SettingDialog.UseAtIdSupplement = _cfgCommon.UseAtIdSupplement
728         SettingDialog.UseHashSupplement = _cfgCommon.UseHashSupplement
729         SettingDialog.PreviewEnable = _cfgCommon.PreviewEnable
730         AtIdSupl = New AtIdSupplement(SettingAtIdList.Load().AtIdList, "@")
731
732         SettingDialog.IsMonospace = _cfgCommon.IsMonospace
733         If SettingDialog.IsMonospace Then
734             detailHtmlFormatHeader = detailHtmlFormatMono1
735             detailHtmlFormatFooter = detailHtmlFormatMono7
736         Else
737             detailHtmlFormatHeader = detailHtmlFormat1
738             detailHtmlFormatFooter = detailHtmlFormat7
739         End If
740         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
741         If SettingDialog.IsMonospace Then
742             detailHtmlFormatHeader += detailHtmlFormatMono6
743         Else
744             detailHtmlFormatHeader += detailHtmlFormat6
745         End If
746         Me.IdeographicSpaceToSpaceToolStripMenuItem.Checked = _cfgCommon.WideSpaceConvert
747         Me.ToolStripFocusLockMenuItem.Checked = _cfgCommon.FocusLockToStatusText
748
749         'Dim statregex As New Regex("^0*")
750         SettingDialog.RecommendStatusText = " [TWNv" + Regex.Replace(fileVersion.Replace(".", ""), "^0*", "") + "]"
751
752         '書式指定文字列エラーチェック
753         Try
754             If DateTime.Now.ToString(SettingDialog.DateTimeFormat).Length = 0 Then
755                 ' このブロックは絶対に実行されないはず
756                 ' 変換が成功した場合にLengthが0にならない
757                 SettingDialog.DateTimeFormat = "yyyy/MM/dd H:mm:ss"
758             End If
759         Catch ex As FormatException
760             ' FormatExceptionが発生したら初期値を設定 (=yyyy/MM/dd H:mm:ssとみなされる)
761             SettingDialog.DateTimeFormat = "yyyy/MM/dd H:mm:ss"
762         End Try
763
764         SettingDialog.Nicoms = _cfgCommon.Nicoms
765         SettingDialog.HotkeyEnabled = _cfgCommon.HotkeyEnabled
766         SettingDialog.HotkeyMod = _cfgCommon.HotkeyModifier
767         SettingDialog.HotkeyKey = _cfgCommon.HotkeyKey
768         SettingDialog.HotkeyValue = _cfgCommon.HotkeyValue
769
770         SettingDialog.BlinkNewMentions = _cfgCommon.BlinkNewMentions
771
772         SettingDialog.UseAdditionalCount = _cfgCommon.UseAdditionalCount
773         SettingDialog.MoreCountApi = _cfgCommon.MoreCountApi
774         SettingDialog.FirstCountApi = _cfgCommon.FirstCountApi
775         SettingDialog.SearchCountApi = _cfgCommon.SearchCountApi
776         SettingDialog.FavoritesCountApi = _cfgCommon.FavoritesCountApi
777         SettingDialog.UserTimelineCountApi = _cfgCommon.UserTimelineCountApi
778         SettingDialog.ListCountApi = _cfgCommon.ListCountApi
779
780         SettingDialog.UserstreamStartup = _cfgCommon.UserstreamStartup
781         SettingDialog.UserstreamPeriodInt = _cfgCommon.UserstreamPeriod
782         SettingDialog.OpenUserTimeline = _cfgCommon.OpenUserTimeline
783
784         'ハッシュタグ関連
785         HashSupl = New AtIdSupplement(_cfgCommon.HashTags, "#")
786         HashMgr = New HashtagManage(HashSupl, _
787                                 _cfgCommon.HashTags.ToArray, _
788                                 _cfgCommon.HashSelected, _
789                                 _cfgCommon.HashIsPermanent, _
790                                 _cfgCommon.HashIsHead)
791         If HashMgr.UseHash <> "" AndAlso HashMgr.IsPermanent Then HashStripSplitButton.Text = HashMgr.UseHash
792
793         _initial = True
794
795         'アイコンリスト作成
796         Try
797             TIconDic = New ImageDictionary(5)
798         Catch ex As Exception
799             MessageBox.Show("Please install [.NET Framework 4 (Full)].")
800             Application.Exit()
801             Exit Sub
802         End Try
803         DirectCast(Me.TIconDic, ImageDictionary).PauseGetImage = False
804
805         Dim saveRequired As Boolean = False
806         'ユーザー名、パスワードが未設定なら設定画面を表示(初回起動時など)
807         If tw.Username = "" Then
808             saveRequired = True
809             '設定せずにキャンセルされた場合はプログラム終了
810             If SettingDialog.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
811                 Application.Exit()  '強制終了
812                 Exit Sub
813             End If
814             '設定されたが、依然ユーザー名とパスワードが未設定ならプログラム終了
815             If tw.Username = "" Then
816                 Application.Exit()  '強制終了
817                 Exit Sub
818             End If
819             '新しい設定を反映
820             'フォント&文字色&背景色保持
821             _fntUnread = SettingDialog.FontUnread
822             _clUnread = SettingDialog.ColorUnread
823             _fntReaded = SettingDialog.FontReaded
824             _clReaded = SettingDialog.ColorReaded
825             _clFav = SettingDialog.ColorFav
826             _clOWL = SettingDialog.ColorOWL
827             _clRetweet = SettingDialog.ColorRetweet
828             _fntDetail = SettingDialog.FontDetail
829             _clDetail = SettingDialog.ColorDetail
830             _clDetailLink = SettingDialog.ColorDetailLink
831             _clDetailBackcolor = SettingDialog.ColorDetailBackcolor
832             _clSelf = SettingDialog.ColorSelf
833             _clAtSelf = SettingDialog.ColorAtSelf
834             _clTarget = SettingDialog.ColorTarget
835             _clAtTarget = SettingDialog.ColorAtTarget
836             _clAtFromTarget = SettingDialog.ColorAtFromTarget
837             _clAtTo = SettingDialog.ColorAtTo
838             _clListBackcolor = SettingDialog.ColorListBackcolor
839             _clInputBackcolor = SettingDialog.ColorInputBackcolor
840             _clInputFont = SettingDialog.ColorInputFont
841             _fntInputFont = SettingDialog.FontInputFont
842             _brsForeColorUnread.Dispose()
843             _brsForeColorReaded.Dispose()
844             _brsForeColorFav.Dispose()
845             _brsForeColorOWL.Dispose()
846             _brsForeColorRetweet.Dispose()
847             _brsForeColorUnread = New SolidBrush(_clUnread)
848             _brsForeColorReaded = New SolidBrush(_clReaded)
849             _brsForeColorFav = New SolidBrush(_clFav)
850             _brsForeColorOWL = New SolidBrush(_clOWL)
851             _brsForeColorRetweet = New SolidBrush(_clRetweet)
852             _brsBackColorMine.Dispose()
853             _brsBackColorAt.Dispose()
854             _brsBackColorYou.Dispose()
855             _brsBackColorAtYou.Dispose()
856             _brsBackColorAtFromTarget.Dispose()
857             _brsBackColorAtTo.Dispose()
858             _brsBackColorNone.Dispose()
859             _brsBackColorMine = New SolidBrush(_clSelf)
860             _brsBackColorAt = New SolidBrush(_clAtSelf)
861             _brsBackColorYou = New SolidBrush(_clTarget)
862             _brsBackColorAtYou = New SolidBrush(_clAtTarget)
863             _brsBackColorAtFromTarget = New SolidBrush(_clAtFromTarget)
864             _brsBackColorAtTo = New SolidBrush(_clAtTo)
865             _brsBackColorNone = New SolidBrush(_clListBackcolor)
866
867             If SettingDialog.IsMonospace Then
868                 detailHtmlFormatHeader = detailHtmlFormatMono1
869                 detailHtmlFormatFooter = detailHtmlFormatMono7
870             Else
871                 detailHtmlFormatHeader = detailHtmlFormat1
872                 detailHtmlFormatFooter = detailHtmlFormat7
873             End If
874             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
875             If SettingDialog.IsMonospace Then
876                 detailHtmlFormatHeader += detailHtmlFormatMono6
877             Else
878                 detailHtmlFormatHeader += detailHtmlFormat6
879             End If
880             '他の設定項目は、随時設定画面で保持している値を読み出して使用
881         End If
882
883         If SettingDialog.HotkeyEnabled Then
884             '''グローバルホットキーの登録
885             Dim modKey As HookGlobalHotkey.ModKeys = HookGlobalHotkey.ModKeys.None
886             If (SettingDialog.HotkeyMod And Keys.Alt) = Keys.Alt Then modKey = modKey Or HookGlobalHotkey.ModKeys.Alt
887             If (SettingDialog.HotkeyMod And Keys.Control) = Keys.Control Then modKey = modKey Or HookGlobalHotkey.ModKeys.Ctrl
888             If (SettingDialog.HotkeyMod And Keys.Shift) = Keys.Shift Then modKey = modKey Or HookGlobalHotkey.ModKeys.Shift
889             If (SettingDialog.HotkeyMod And Keys.LWin) = Keys.LWin Then modKey = modKey Or HookGlobalHotkey.ModKeys.Win
890
891             _hookGlobalHotkey.RegisterOriginalHotkey(SettingDialog.HotkeyKey, SettingDialog.HotkeyValue, modKey)
892         End If
893
894         'Twitter用通信クラス初期化
895         HttpConnection.InitializeConnection(SettingDialog.DefaultTimeOut, _
896                                             SettingDialog.SelectedProxyType, _
897                                             SettingDialog.ProxyAddress, _
898                                             SettingDialog.ProxyPort, _
899                                             SettingDialog.ProxyUser, _
900                                             SettingDialog.ProxyPassword)
901
902         tw.RestrictFavCheck = SettingDialog.RestrictFavCheck
903         tw.ReadOwnPost = SettingDialog.ReadOwnPost
904         tw.UseSsl = SettingDialog.UseSsl
905         ShortUrl.IsResolve = SettingDialog.TinyUrlResolve
906         ShortUrl.BitlyId = SettingDialog.BitlyUser
907         ShortUrl.BitlyKey = SettingDialog.BitlyPwd
908         HttpTwitter.TwitterUrl = _cfgCommon.TwitterUrl
909         HttpTwitter.TwitterSearchUrl = _cfgCommon.TwitterSearchUrl
910         tw.TrackWord = _cfgCommon.TrackWord
911         TrackToolStripMenuItem.Checked = Not String.IsNullOrEmpty(tw.TrackWord)
912         tw.AllAtReply = _cfgCommon.AllAtReply
913         AllrepliesToolStripMenuItem.Checked = tw.AllAtReply
914
915         Outputz.Key = SettingDialog.OutputzKey
916         Outputz.Enabled = SettingDialog.OutputzEnabled
917         Select Case SettingDialog.OutputzUrlmode
918             Case OutputzUrlmode.twittercom
919                 Outputz.OutUrl = "http://twitter.com/"
920             Case OutputzUrlmode.twittercomWithUsername
921                 Outputz.OutUrl = "http://twitter.com/" + tw.Username
922         End Select
923
924         '画像投稿サービス
925         Me.pictureService = New Dictionary(Of String, IMultimediaShareService) From {
926             {"TwitPic", New TwitPic(tw)},
927             {"img.ly", New imgly(tw)},
928             {"yfrog", New yfrog(tw)},
929             {"Plixi", New Plixi(tw)}}
930         SetImageServiceCombo()
931         ImageSelectionPanel.Enabled = False
932
933         ImageServiceCombo.SelectedIndex = _cfgCommon.UseImageService
934
935         'ウィンドウ設定
936         Me.ClientSize = _cfgLocal.FormSize
937         _mySize = _cfgLocal.FormSize                     'サイズ保持(最小化・最大化されたまま終了した場合の対応用)
938         _myLoc = _cfgLocal.FormLocation
939         'タイトルバー領域
940         If Me.WindowState <> FormWindowState.Minimized Then
941             Me.DesktopLocation = _cfgLocal.FormLocation
942             Dim tbarRect As New Rectangle(Me.Location, New Size(_mySize.Width, SystemInformation.CaptionHeight))
943             Dim outOfScreen As Boolean = True
944             If Screen.AllScreens.Length = 1 Then    'ハングするとの報告
945                 For Each scr As Screen In Screen.AllScreens
946                     If Not Rectangle.Intersect(tbarRect, scr.Bounds).IsEmpty Then
947                         outOfScreen = False
948                         Exit For
949                     End If
950                 Next
951                 If outOfScreen Then
952                     Me.DesktopLocation = New Point(0, 0)
953                     _myLoc = Me.DesktopLocation
954                 End If
955             End If
956         End If
957         Me.TopMost = SettingDialog.AlwaysTop
958         _mySpDis = _cfgLocal.SplitterDistance
959         _mySpDis2 = _cfgLocal.StatusTextHeight
960         _mySpDis3 = _cfgLocal.PreviewDistance
961         If _mySpDis3 = -1 Then
962             _mySpDis3 = _mySize.Width - 150
963             If _mySpDis3 < 1 Then _mySpDis3 = 50
964             _cfgLocal.PreviewDistance = _mySpDis3
965         End If
966         MultiLineMenuItem.Checked = _cfgLocal.StatusMultiline
967         'Me.Tween_ClientSizeChanged(Me, Nothing)
968         PlaySoundMenuItem.Checked = SettingDialog.PlaySound
969         Me.PlaySoundFileMenuItem.Checked = SettingDialog.PlaySound
970         '入力欄
971         StatusText.Font = _fntInputFont
972         StatusText.ForeColor = _clInputFont
973
974         '全新着通知のチェック状態により、Reply&DMの新着通知有効無効切り替え(タブ別設定にするため削除予定)
975         If SettingDialog.UnreadManage = False Then
976             ReadedStripMenuItem.Enabled = False
977             UnreadStripMenuItem.Enabled = False
978         End If
979
980         'タイマー設定
981         TimerTimeline.AutoReset = True
982         TimerTimeline.SynchronizingObject = Me
983         'Recent取得間隔
984         TimerTimeline.Interval = 1000
985         TimerTimeline.Enabled = True
986
987         '更新中アイコンアニメーション間隔
988         TimerRefreshIcon.Interval = 200
989         TimerRefreshIcon.Enabled = True
990
991         '状態表示部の初期化(画面右下)
992         StatusLabel.Text = ""
993         StatusLabel.AutoToolTip = False
994         StatusLabel.ToolTipText = ""
995         '文字カウンタ初期化
996         lblLen.Text = GetRestStatusCount(True, False).ToString()
997
998         ''''''''''''''''''''''''''''''''''''''''
999         _statuses.SortOrder = DirectCast(_cfgCommon.SortOrder, System.Windows.Forms.SortOrder)
1000         Dim mode As IdComparerClass.ComparerMode
1001         Select Case _cfgCommon.SortColumn
1002             Case 0, 5, 6    '0:アイコン,5:未読マーク,6:プロテクト・フィルターマーク
1003                 'ソートしない
1004                 mode = IdComparerClass.ComparerMode.Id  'Idソートに読み替え
1005             Case 1  'ニックネーム
1006                 mode = IdComparerClass.ComparerMode.Nickname
1007             Case 2  '本文
1008                 mode = IdComparerClass.ComparerMode.Data
1009             Case 3  '時刻=発言Id
1010                 mode = IdComparerClass.ComparerMode.Id
1011             Case 4  '名前
1012                 mode = IdComparerClass.ComparerMode.Name
1013             Case 7  'Source
1014                 mode = IdComparerClass.ComparerMode.Source
1015         End Select
1016         _statuses.SortMode = mode
1017         ''''''''''''''''''''''''''''''''''''''''
1018
1019         Select Case SettingDialog.IconSz
1020             Case IconSizes.IconNone
1021                 _iconSz = 0
1022             Case IconSizes.Icon16
1023                 _iconSz = 16
1024             Case IconSizes.Icon24
1025                 _iconSz = 26
1026             Case IconSizes.Icon48
1027                 _iconSz = 48
1028             Case IconSizes.Icon48_2
1029                 _iconSz = 48
1030                 _iconCol = True
1031         End Select
1032         If _iconSz = 0 Then
1033             tw.GetIcon = False
1034         Else
1035             tw.GetIcon = True
1036             tw.IconSize = _iconSz
1037         End If
1038         tw.TinyUrlResolve = SettingDialog.TinyUrlResolve
1039
1040         '発言詳細部アイコンをリストアイコンにサイズ変更
1041         Dim sz As Integer = _iconSz
1042         If _iconSz = 0 Then
1043             sz = 16
1044         End If
1045
1046         tw.DetailIcon = TIconDic
1047
1048         StatusLabel.Text = My.Resources.Form1_LoadText1       '画面右下の状態表示を変更
1049         StatusLabelUrl.Text = ""            '画面左下のリンク先URL表示部を初期化
1050         NameLabel.Text = ""                 '発言詳細部名前ラベル初期化
1051         DateTimeLabel.Text = ""             '発言詳細部日時ラベル初期化
1052         SourceLinkLabel.Text = ""           'Source部分初期化
1053
1054         '<<<<<<<<タブ関連>>>>>>>
1055         'デフォルトタブの存在チェック、ない場合には追加
1056         If _statuses.GetTabByType(TabUsageType.Home) Is Nothing Then
1057             If Not _statuses.Tabs.ContainsKey(DEFAULTTAB.RECENT) Then
1058                 _statuses.AddTab(DEFAULTTAB.RECENT, TabUsageType.Home, Nothing)
1059             Else
1060                 _statuses.Tabs(DEFAULTTAB.RECENT).TabType = TabUsageType.Home
1061             End If
1062         End If
1063         If _statuses.GetTabByType(TabUsageType.Mentions) Is Nothing Then
1064             If Not _statuses.Tabs.ContainsKey(DEFAULTTAB.REPLY) Then
1065                 _statuses.AddTab(DEFAULTTAB.REPLY, TabUsageType.Mentions, Nothing)
1066             Else
1067                 _statuses.Tabs(DEFAULTTAB.REPLY).TabType = TabUsageType.Mentions
1068             End If
1069         End If
1070         If _statuses.GetTabByType(TabUsageType.DirectMessage) Is Nothing Then
1071             If Not _statuses.Tabs.ContainsKey(DEFAULTTAB.DM) Then
1072                 _statuses.AddTab(DEFAULTTAB.DM, TabUsageType.DirectMessage, Nothing)
1073             Else
1074                 _statuses.Tabs(DEFAULTTAB.DM).TabType = TabUsageType.DirectMessage
1075             End If
1076         End If
1077         If _statuses.GetTabByType(TabUsageType.Favorites) Is Nothing Then
1078             If Not _statuses.Tabs.ContainsKey(DEFAULTTAB.FAV) Then
1079                 _statuses.AddTab(DEFAULTTAB.FAV, TabUsageType.Favorites, Nothing)
1080             Else
1081                 _statuses.Tabs(DEFAULTTAB.FAV).TabType = TabUsageType.Favorites
1082             End If
1083         End If
1084         For Each tn As String In _statuses.Tabs.Keys
1085             If _statuses.Tabs(tn).TabType = TabUsageType.Undefined Then
1086                 _statuses.Tabs(tn).TabType = TabUsageType.UserDefined
1087             End If
1088             If Not AddNewTab(tn, True, _statuses.Tabs(tn).TabType, _statuses.Tabs(tn).ListInfo) Then Throw New Exception(My.Resources.TweenMain_LoadText1)
1089         Next
1090
1091         Me.JumpReadOpMenuItem.ShortcutKeyDisplayString = "Space"
1092         CopySTOTMenuItem.ShortcutKeyDisplayString = "Ctrl+C"
1093         CopyURLMenuItem.ShortcutKeyDisplayString = "Ctrl+Shift+C"
1094         CopyUserIdStripMenuItem.ShortcutKeyDisplayString = "Shift+Alt+C"
1095
1096         If SettingDialog.MinimizeToTray = False OrElse Me.WindowState <> FormWindowState.Minimized Then
1097             Me.Visible = True
1098         End If
1099         _curTab = ListTab.SelectedTab
1100         _curItemIndex = -1
1101         _curList = DirectCast(_curTab.Tag, DetailsListView)
1102         SetMainWindowTitle()
1103         SetNotifyIconText()
1104
1105         If SettingDialog.TabIconDisp Then
1106             ListTab.DrawMode = TabDrawMode.Normal
1107         Else
1108             ListTab.DrawMode = TabDrawMode.OwnerDrawFixed
1109             AddHandler ListTab.DrawItem, AddressOf ListTab_DrawItem
1110             ListTab.ImageList = Nothing
1111         End If
1112
1113         _ignoreConfigSave = False
1114         Me.TweenMain_Resize(Nothing, Nothing)
1115         If saveRequired Then SaveConfigsAll(False)
1116     End Sub
1117
1118     Private Sub spaceKeyCanceler_SpaceCancel(ByVal sender As Object, ByVal e As EventArgs)
1119         JumpUnreadMenuItem_Click(Nothing, Nothing)
1120     End Sub
1121
1122     Private Sub ListTab_DrawItem( _
1123             ByVal sender As Object, ByVal e As DrawItemEventArgs)
1124         Dim txt As String
1125         Try
1126             txt = ListTab.TabPages(e.Index).Text
1127         Catch ex As Exception
1128             Exit Sub
1129         End Try
1130
1131         e.Graphics.FillRectangle(System.Drawing.SystemBrushes.Control, e.Bounds)
1132         If e.State = DrawItemState.Selected Then
1133             e.DrawFocusRectangle()
1134         End If
1135         Dim fore As Brush
1136         Try
1137             If _statuses.Tabs(txt).UnreadCount > 0 Then
1138                 fore = Brushes.Red
1139             Else
1140                 fore = System.Drawing.SystemBrushes.ControlText
1141             End If
1142         Catch ex As Exception
1143             fore = System.Drawing.SystemBrushes.ControlText
1144         End Try
1145         e.Graphics.DrawString(txt, e.Font, fore, e.Bounds, sfTab)
1146     End Sub
1147
1148     Private Sub LoadConfig()
1149         Dim needToSave As Boolean = False
1150         _cfgCommon = SettingCommon.Load()
1151         _cfgLocal = SettingLocal.Load()
1152         Dim tabs As List(Of TabClass) = SettingTabs.Load().Tabs
1153         For Each tb As TabClass In tabs
1154             Try
1155                 _statuses.Tabs.Add(tb.TabName, tb)
1156             Catch ex As Exception
1157                 tb.TabName = _statuses.GetUniqueTabName()
1158                 _statuses.Tabs.Add(tb.TabName, tb)
1159             End Try
1160         Next
1161         If _statuses.Tabs.Count = 0 Then
1162             _statuses.AddTab(DEFAULTTAB.RECENT, TabUsageType.Home, Nothing)
1163             _statuses.AddTab(DEFAULTTAB.REPLY, TabUsageType.Mentions, Nothing)
1164             _statuses.AddTab(DEFAULTTAB.DM, TabUsageType.DirectMessage, Nothing)
1165             _statuses.AddTab(DEFAULTTAB.FAV, TabUsageType.Favorites, Nothing)
1166         End If
1167     End Sub
1168
1169     'Private Sub ConvertConfig()
1170     '    '新タブ設定ファイル存在チェック
1171     '    If System.IO.File.Exists(SettingTabs.GetSettingFilePath("")) Then
1172     '        LoadConfig()
1173     '        Exit Sub
1174     '    End If
1175     '    'LoadOldConfig()
1176     'End Sub
1177
1178     Private Sub TimerTimeline_Elapsed(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerTimeline.Elapsed
1179         Static homeCounter As Integer = 0
1180         Static mentionCounter As Integer = 0
1181         Static dmCounter As Integer = 0
1182         Static pubSearchCounter As Integer = 0
1183         Static userTimelineCounter As Integer = 0
1184         Static listsCounter As Integer = 0
1185         Static usCounter As Integer = 0
1186         Static ResumeWait As Integer = 0
1187         Static refreshFollowers As Integer = 0
1188
1189         If homeCounter > 0 Then Interlocked.Decrement(homeCounter)
1190         If mentionCounter > 0 Then Interlocked.Decrement(mentionCounter)
1191         If dmCounter > 0 Then Interlocked.Decrement(dmCounter)
1192         If pubSearchCounter > 0 Then Interlocked.Decrement(pubSearchCounter)
1193         If userTimelineCounter > 0 Then Interlocked.Decrement(userTimelineCounter)
1194         If listsCounter > 0 Then Interlocked.Decrement(listsCounter)
1195         If usCounter > 0 Then Interlocked.Decrement(usCounter)
1196         Interlocked.Increment(refreshFollowers)
1197
1198         ''タイマー初期化
1199         If homeCounter <= 0 AndAlso SettingDialog.TimelinePeriodInt > 0 Then
1200             Interlocked.Exchange(homeCounter, SettingDialog.TimelinePeriodInt)
1201             If Not tw.IsUserstreamDataReceived Then GetTimeline(WORKERTYPE.Timeline, 1, 0, "")
1202         End If
1203         If mentionCounter <= 0 AndAlso SettingDialog.ReplyPeriodInt > 0 Then
1204             Interlocked.Exchange(mentionCounter, SettingDialog.ReplyPeriodInt)
1205             If Not tw.IsUserstreamDataReceived Then GetTimeline(WORKERTYPE.Reply, 1, 0, "")
1206         End If
1207         If dmCounter <= 0 AndAlso SettingDialog.DMPeriodInt > 0 Then
1208             Interlocked.Exchange(dmCounter, SettingDialog.DMPeriodInt)
1209             If Not tw.IsUserstreamDataReceived Then GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0, "")
1210         End If
1211         If pubSearchCounter <= 0 AndAlso SettingDialog.PubSearchPeriodInt > 0 Then
1212             Interlocked.Exchange(pubSearchCounter, SettingDialog.PubSearchPeriodInt)
1213             GetTimeline(WORKERTYPE.PublicSearch, 1, 0, "")
1214         End If
1215         If userTimelineCounter <= 0 AndAlso SettingDialog.UserTimelinePeriodInt > 0 Then
1216             Interlocked.Exchange(userTimelineCounter, SettingDialog.UserTimelinePeriodInt)
1217             GetTimeline(WORKERTYPE.UserTimeline, 1, 0, "")
1218         End If
1219         If listsCounter <= 0 AndAlso SettingDialog.ListsPeriodInt > 0 Then
1220             Interlocked.Exchange(listsCounter, SettingDialog.ListsPeriodInt)
1221             GetTimeline(WORKERTYPE.List, 1, 0, "")
1222         End If
1223         If usCounter <= 0 AndAlso SettingDialog.UserstreamPeriodInt > 0 Then
1224             Interlocked.Exchange(usCounter, SettingDialog.UserstreamPeriodInt)
1225             If Me._isActiveUserstream Then RefreshTimeline(True)
1226         End If
1227         If refreshFollowers > 3600 Then
1228             Interlocked.Exchange(refreshFollowers, 0)
1229             doGetFollowersMenu()
1230         End If
1231         If osResumed Then
1232             Interlocked.Increment(ResumeWait)
1233             If ResumeWait > 30 Then
1234                 osResumed = False
1235                 Interlocked.Exchange(ResumeWait, 0)
1236                 GetTimeline(WORKERTYPE.Timeline, 1, 0, "")
1237                 GetTimeline(WORKERTYPE.Reply, 1, 0, "")
1238                 GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0, "")
1239             End If
1240         End If
1241     End Sub
1242
1243     Private Sub RefreshTimeline(ByVal isUserStream As Boolean)
1244         If isUserStream Then Me.RefreshTasktrayIcon(True)
1245         'スクロール制御準備
1246         Dim smode As Integer = -1    '-1:制御しない,-2:最新へ,その他:topitem使用
1247         Dim topId As Long = GetScrollPos(smode)
1248         Dim befCnt As Integer = _curList.VirtualListSize
1249
1250         '現在の選択状態を退避
1251         Dim selId As New Dictionary(Of String, Long())
1252         Dim focusedId As New Dictionary(Of String, Long)
1253         SaveSelectedStatus(selId, focusedId)
1254
1255         'mentionsの更新前件数を保持
1256         Dim dmCount As Integer = _statuses.GetTabByType(TabUsageType.DirectMessage).AllCount
1257
1258         '更新確定
1259         Dim notifyPosts() As PostClass = Nothing
1260         Dim soundFile As String = ""
1261         Dim addCount As Integer = 0
1262         Dim isMention As Boolean = False
1263         Dim isDelete As Boolean = False
1264         addCount = _statuses.SubmitUpdate(soundFile, notifyPosts, isMention, isDelete, isUserStream)
1265
1266         If _endingFlag Then Exit Sub
1267
1268         'リストに反映&選択状態復元
1269         Try
1270             For Each tab As TabPage In ListTab.TabPages
1271                 Dim lst As DetailsListView = DirectCast(tab.Tag, DetailsListView)
1272                 Dim tabInfo As TabClass = _statuses.Tabs(tab.Text)
1273                 lst.BeginUpdate()
1274                 If isDelete OrElse lst.VirtualListSize <> tabInfo.AllCount Then
1275                     If lst.Equals(_curList) Then
1276                         _itemCache = Nothing
1277                         _postCache = Nothing
1278                     End If
1279                     Try
1280                         lst.VirtualListSize = tabInfo.AllCount 'リスト件数更新
1281                     Catch ex As Exception
1282                         'アイコン描画不具合あり?
1283                     End Try
1284                     Me.SelectListItem(lst, _
1285                                       _statuses.IndexOf(tab.Text, selId(tab.Text)), _
1286                                       _statuses.IndexOf(tab.Text, focusedId(tab.Text)))
1287                 End If
1288                 lst.EndUpdate()
1289                 If tabInfo.UnreadCount > 0 Then
1290                     If SettingDialog.TabIconDisp Then
1291                         If tab.ImageIndex = -1 Then tab.ImageIndex = 0 'タブアイコン
1292                     End If
1293                 End If
1294             Next
1295             If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
1296         Catch ex As Exception
1297             'ex.Data("Msg") = "Ref1, UseAPI=" + SettingDialog.UseAPI.ToString
1298             'Throw
1299         End Try
1300
1301         'スクロール制御後処理
1302         If smode <> -1 Then
1303             Try
1304                 If befCnt <> _curList.VirtualListSize Then
1305                     Select Case smode
1306                         Case -3
1307                             '最上行
1308                             If _curList.VirtualListSize > 0 Then _curList.EnsureVisible(0)
1309                         Case -2
1310                             '最下行へ
1311                             If _curList.VirtualListSize > 0 Then _curList.EnsureVisible(_curList.VirtualListSize - 1)
1312                         Case -1
1313                             '制御しない
1314                         Case Else
1315                             '表示位置キープ
1316                             If _curList.VirtualListSize > 0 AndAlso _statuses.IndexOf(_curTab.Text, topId) > -1 Then
1317                                 _curList.EnsureVisible(_curList.VirtualListSize - 1)
1318                                 _curList.EnsureVisible(_statuses.IndexOf(_curTab.Text, topId))
1319                             End If
1320                     End Select
1321                 End If
1322             Catch ex As Exception
1323                 ex.Data("Msg") = "Ref2"
1324                 Throw
1325             End Try
1326         End If
1327
1328         '新着通知
1329         NotifyNewPosts(notifyPosts,
1330                        soundFile,
1331                        addCount,
1332                        isMention OrElse dmCount <> _statuses.GetTabByType(TabUsageType.DirectMessage).AllCount)
1333
1334         SetMainWindowTitle()
1335         If Not StatusLabelUrl.Text.StartsWith("http") Then SetStatusLabelUrl()
1336
1337         HashSupl.AddRangeItem(tw.GetHashList)
1338
1339     End Sub
1340
1341     Private Function GetScrollPos(ByRef smode As Integer) As Long
1342         Dim topId As Long = -1
1343         If _curList IsNot Nothing AndAlso _curTab IsNot Nothing AndAlso _curList.VirtualListSize > 0 Then
1344             If _statuses.SortMode = IdComparerClass.ComparerMode.Id Then
1345                 If _statuses.SortOrder = SortOrder.Ascending Then
1346                     'Id昇順
1347                     If ListLockMenuItem.Checked Then
1348                         '制御しない
1349                         smode = -1
1350                         ''現在表示位置へ強制スクロール
1351                         'If _curList.TopItem IsNot Nothing Then topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index)
1352                         'smode = 0
1353                     Else
1354                         '最下行が表示されていたら、最下行へ強制スクロール。最下行が表示されていなかったら制御しない
1355                         Dim _item As ListViewItem
1356                         _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1)   '一番下
1357                         If _item Is Nothing Then _item = _curList.Items(_curList.Items.Count - 1)
1358                         If _item.Index = _curList.Items.Count - 1 Then
1359                             smode = -2
1360                         Else
1361                             smode = -1
1362                             'If _curList.TopItem IsNot Nothing Then topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index)
1363                             'smode = 0
1364                         End If
1365                     End If
1366                 Else
1367                     'Id降順
1368                     If ListLockMenuItem.Checked Then
1369                         '現在表示位置へ強制スクロール
1370                         If _curList.TopItem IsNot Nothing Then topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index)
1371                         smode = 0
1372                     Else
1373                         '最上行が表示されていたら、制御しない。最上行が表示されていなかったら、現在表示位置へ強制スクロール
1374                         Dim _item As ListViewItem
1375
1376                         _item = _curList.GetItemAt(0, 10)     '一番上
1377                         If _item Is Nothing Then _item = _curList.Items(0)
1378                         If _item.Index = 0 Then
1379                             smode = -3  '最上行
1380                         Else
1381                             If _curList.TopItem IsNot Nothing Then topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index)
1382                             smode = 0
1383                         End If
1384                     End If
1385                 End If
1386             Else
1387                 '現在表示位置へ強制スクロール
1388                 If _curList.TopItem IsNot Nothing Then topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index)
1389                 smode = 0
1390             End If
1391         Else
1392             smode = -1
1393         End If
1394         Return topId
1395     End Function
1396
1397     Private Sub SaveSelectedStatus(ByVal selId As Dictionary(Of String, Long()), ByVal focusedId As Dictionary(Of String, Long))
1398         If _endingFlag Then Exit Sub
1399         For Each tab As TabPage In ListTab.TabPages
1400             Dim lst As DetailsListView = DirectCast(tab.Tag, DetailsListView)
1401             If lst.SelectedIndices.Count > 0 AndAlso lst.SelectedIndices.Count < 61 Then
1402                 selId.Add(tab.Text, _statuses.GetId(tab.Text, lst.SelectedIndices))
1403             Else
1404                 selId.Add(tab.Text, New Long(0) {-2})
1405             End If
1406             If lst.FocusedItem IsNot Nothing Then
1407                 focusedId.Add(tab.Text, _statuses.GetId(tab.Text, lst.FocusedItem.Index))
1408             Else
1409                 focusedId.Add(tab.Text, -2)
1410             End If
1411         Next
1412
1413     End Sub
1414
1415     Private Overloads Function BalloonRequired() As Boolean
1416         Return BalloonRequired(New Twitter.FormattedEvent With {.Eventtype = EVENTTYPE.None})
1417     End Function
1418
1419     Private Function IsEventNotifyAsEventType(ByVal type As EVENTTYPE) As Boolean
1420         Return SettingDialog.EventNotifyEnabled AndAlso CBool(type And SettingDialog.EventNotifyFlag) OrElse type = EVENTTYPE.None
1421     End Function
1422
1423     Private Function IsMyEventNotityAsEventType(ByVal ev As Twitter.FormattedEvent) As Boolean
1424         Return If(CBool(ev.Eventtype And SettingDialog.IsMyEventNotifyFlag), True, Not ev.IsMe)
1425     End Function
1426
1427     Private Overloads Function BalloonRequired(ByVal ev As Twitter.FormattedEvent) As Boolean
1428         If (
1429             IsEventNotifyAsEventType(ev.Eventtype) AndAlso IsMyEventNotityAsEventType(ev) AndAlso
1430             (NewPostPopMenuItem.Checked OrElse (SettingDialog.ForceEventNotify AndAlso ev.Eventtype <> EVENTTYPE.None)) AndAlso
1431             Not _initial AndAlso
1432             (
1433                 (
1434                     SettingDialog.LimitBalloon AndAlso
1435                     (
1436                         Me.WindowState = FormWindowState.Minimized OrElse
1437                         Not Me.Visible OrElse
1438                         Form.ActiveForm Is Nothing
1439                         )
1440                     ) OrElse
1441                 Not SettingDialog.LimitBalloon
1442                 )
1443             ) AndAlso
1444         Not IsScreenSaverRunning() Then
1445             Return True
1446         Else
1447             Return False
1448         End If
1449     End Function
1450
1451     Private Sub NotifyNewPosts(ByVal notifyPosts() As PostClass, ByVal soundFile As String, ByVal addCount As Integer, ByVal newMentions As Boolean)
1452         If notifyPosts IsNot Nothing AndAlso _
1453             notifyPosts.Count > 0 AndAlso _
1454             Me.SettingDialog.ReadOwnPost AndAlso _
1455             notifyPosts.All(Function(post) post.UserId.ToString() = tw.UserIdNo OrElse post.ScreenName = tw.Username) Then
1456             Exit Sub
1457         End If
1458
1459         '新着通知
1460         If BalloonRequired() Then
1461             If notifyPosts IsNot Nothing AndAlso notifyPosts.Length > 0 Then
1462                 Dim sb As New StringBuilder
1463                 Dim reply As Boolean = False
1464                 Dim dm As Boolean = False
1465                 For Each post As PostClass In notifyPosts
1466                     If post.IsReply AndAlso Not post.IsExcludeReply Then reply = True
1467                     If post.IsDm Then dm = True
1468                     If sb.Length > 0 Then sb.Append(System.Environment.NewLine)
1469                     Select Case SettingDialog.NameBalloon
1470                         Case NameBalloonEnum.UserID
1471                             sb.Append(post.ScreenName).Append(" : ")
1472                         Case NameBalloonEnum.NickName
1473                             sb.Append(post.Nickname).Append(" : ")
1474                     End Select
1475                     sb.Append(post.TextFromApi)
1476                 Next
1477                 If SettingDialog.DispUsername Then NotifyIcon1.BalloonTipTitle = tw.Username + " - " Else NotifyIcon1.BalloonTipTitle = ""
1478                 If dm Then
1479                     NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning
1480                     NotifyIcon1.BalloonTipTitle += "Tween [DM] " + My.Resources.RefreshDirectMessageText1 + " " + addCount.ToString() + My.Resources.RefreshDirectMessageText2
1481                 ElseIf reply Then
1482                     NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning
1483                     NotifyIcon1.BalloonTipTitle += "Tween [Reply!] " + My.Resources.RefreshTimelineText1 + " " + addCount.ToString() + My.Resources.RefreshTimelineText2
1484                 Else
1485                     NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info
1486                     NotifyIcon1.BalloonTipTitle += "Tween " + My.Resources.RefreshTimelineText1 + " " + addCount.ToString() + My.Resources.RefreshTimelineText2
1487                 End If
1488                 Dim bText As String = sb.ToString
1489                 If String.IsNullOrEmpty(bText) Then Exit Sub
1490                 NotifyIcon1.BalloonTipText = sb.ToString()
1491                 NotifyIcon1.ShowBalloonTip(500)
1492             End If
1493         End If
1494
1495         'サウンド再生
1496         If Not _initial AndAlso SettingDialog.PlaySound AndAlso soundFile <> "" Then
1497             Try
1498                 Dim dir As String = My.Application.Info.DirectoryPath
1499                 If Directory.Exists(Path.Combine(dir, "Sounds")) Then
1500                     dir = Path.Combine(dir, "Sounds")
1501                 End If
1502                 My.Computer.Audio.Play(Path.Combine(dir, soundFile), AudioPlayMode.Background)
1503             Catch ex As Exception
1504
1505             End Try
1506         End If
1507
1508         'mentions新着時に画面ブリンク
1509         If Not _initial AndAlso SettingDialog.BlinkNewMentions AndAlso newMentions AndAlso Form.ActiveForm Is Nothing Then
1510             FlashMyWindow(Me.Handle, FlashSpecification.FlashTray, 3)
1511         End If
1512     End Sub
1513
1514     Private Sub MyList_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
1515         If _curList Is Nothing OrElse _curList.SelectedIndices.Count <> 1 Then Exit Sub
1516
1517         _curItemIndex = _curList.SelectedIndices(0)
1518         If _curItemIndex > _curList.VirtualListSize - 1 Then Exit Sub
1519
1520         _curPost = GetCurTabPost(_curItemIndex)
1521
1522         If SettingDialog.UnreadManage Then _statuses.SetReadAllTab(True, _curTab.Text, _curItemIndex)
1523         'キャッシュの書き換え
1524         ChangeCacheStyleRead(True, _curItemIndex, _curTab)   '既読へ(フォント、文字色)
1525
1526         ColorizeList()
1527         _colorize = True
1528     End Sub
1529
1530     Private Sub ChangeCacheStyleRead(ByVal Read As Boolean, ByVal Index As Integer, ByVal Tab As TabPage)
1531         'Read:True=既読 False=未読
1532         '未読管理していなかったら既読として扱う
1533         If Not _statuses.Tabs(_curTab.Text).UnreadManage OrElse _
1534            Not SettingDialog.UnreadManage Then Read = True
1535
1536         '対象の特定
1537         Dim itm As ListViewItem
1538         Dim post As PostClass
1539         If Tab.Equals(_curTab) AndAlso _itemCache IsNot Nothing AndAlso Index >= _itemCacheIndex AndAlso Index < _itemCacheIndex + _itemCache.Length Then
1540             itm = _itemCache(Index - _itemCacheIndex)
1541             post = _postCache(Index - _itemCacheIndex)
1542         Else
1543             itm = DirectCast(Tab.Tag, DetailsListView).Items(Index)
1544             post = _statuses.Item(Tab.Text, Index)
1545         End If
1546
1547         ChangeItemStyleRead(Read, itm, post, DirectCast(Tab.Tag, DetailsListView))
1548     End Sub
1549
1550     Private Sub ChangeItemStyleRead(ByVal Read As Boolean, ByVal Item As ListViewItem, ByVal Post As PostClass, ByVal DList As DetailsListView)
1551         Dim fnt As Font
1552         'フォント
1553         If Read Then
1554             fnt = _fntReaded
1555             Item.SubItems(5).Text = ""
1556         Else
1557             fnt = _fntUnread
1558             Item.SubItems(5).Text = "★"
1559         End If
1560         '文字色
1561         Dim cl As Color
1562         If Post.IsFav Then
1563             cl = _clFav
1564         ElseIf Post.RetweetedId > 0 Then
1565             cl = _clRetweet
1566         ElseIf Post.IsOwl AndAlso (Post.IsDm OrElse SettingDialog.OneWayLove) Then
1567             cl = _clOWL
1568         ElseIf Read OrElse Not SettingDialog.UseUnreadStyle Then
1569             cl = _clReaded
1570         Else
1571             cl = _clUnread
1572         End If
1573         If DList Is Nothing OrElse Item.Index = -1 Then
1574             Item.ForeColor = cl
1575             If SettingDialog.UseUnreadStyle Then
1576                 Item.Font = fnt
1577             End If
1578         Else
1579             DList.Update()
1580             If SettingDialog.UseUnreadStyle Then
1581                 DList.ChangeItemFontAndColor(Item.Index, cl, fnt)
1582             Else
1583                 DList.ChangeItemForeColor(Item.Index, cl)
1584             End If
1585             'If _itemCache IsNot Nothing Then DList.RedrawItems(_itemCacheIndex, _itemCacheIndex + _itemCache.Length - 1, False)
1586         End If
1587     End Sub
1588
1589     Private Sub ColorizeList()
1590         'Index:更新対象のListviewItem.Index。Colorを返す。
1591         '-1は全キャッシュ。Colorは返さない(ダミーを戻す)
1592         Dim _post As PostClass
1593         If _anchorFlag Then
1594             _post = _anchorPost
1595         Else
1596             _post = _curPost
1597         End If
1598
1599         If _itemCache Is Nothing Then Exit Sub
1600
1601         If _post Is Nothing Then Exit Sub
1602
1603         Try
1604             For cnt As Integer = 0 To _itemCache.Length - 1
1605                 _curList.ChangeItemBackColor(_itemCacheIndex + cnt, JudgeColor(_post, _postCache(cnt)))
1606             Next
1607         Catch ex As Exception
1608         End Try
1609     End Sub
1610
1611     Private Sub ColorizeList(ByVal Item As ListViewItem, ByVal Index As Integer)
1612         'Index:更新対象のListviewItem.Index。Colorを返す。
1613         '-1は全キャッシュ。Colorは返さない(ダミーを戻す)
1614         Dim _post As PostClass
1615         If _anchorFlag Then
1616             _post = _anchorPost
1617         Else
1618             _post = _curPost
1619         End If
1620
1621         Dim tPost As PostClass = GetCurTabPost(Index)
1622
1623         If _post Is Nothing Then Exit Sub
1624
1625         If Item.Index = -1 Then
1626             Item.BackColor = JudgeColor(_post, tPost)
1627         Else
1628             _curList.ChangeItemBackColor(Item.Index, JudgeColor(_post, tPost))
1629         End If
1630     End Sub
1631
1632     Private Function JudgeColor(ByVal BasePost As PostClass, ByVal TargetPost As PostClass) As Color
1633         Dim cl As Color
1634         If TargetPost.StatusId = BasePost.InReplyToStatusId Then
1635             '@先
1636             cl = _clAtTo
1637         ElseIf TargetPost.IsMe Then
1638             '自分=発言者
1639             cl = _clSelf
1640         ElseIf TargetPost.IsReply Then
1641             '自分宛返信
1642             cl = _clAtSelf
1643         ElseIf BasePost.ReplyToList.Contains(TargetPost.ScreenName.ToLower()) Then
1644             '返信先
1645             cl = _clAtFromTarget
1646         ElseIf TargetPost.ReplyToList.Contains(BasePost.ScreenName.ToLower()) Then
1647             'その人への返信
1648             cl = _clAtTarget
1649         ElseIf TargetPost.ScreenName.Equals(BasePost.ScreenName, StringComparison.OrdinalIgnoreCase) Then
1650             '発言者
1651             cl = _clTarget
1652         Else
1653             'その他
1654             cl = _clListBackcolor
1655         End If
1656         Return cl
1657     End Function
1658
1659     Private Sub PostButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PostButton.Click
1660         If StatusText.Text.Trim.Length = 0 Then
1661             If Not ImageSelectionPanel.Enabled Then
1662                 DoRefresh()
1663                 Exit Sub
1664             End If
1665         End If
1666
1667         If Me.ExistCurrentPost AndAlso StatusText.Text.Trim() = String.Format("RT @{0}: {1}", _curPost.ScreenName, _curPost.TextFromApi) Then
1668             Dim rtResult As DialogResult = MessageBox.Show(String.Format(My.Resources.PostButton_Click1, Environment.NewLine),
1669                                                            "Retweet",
1670                                                            MessageBoxButtons.YesNoCancel,
1671                                                            MessageBoxIcon.Question)
1672             Select Case rtResult
1673                 Case Windows.Forms.DialogResult.Yes
1674                     doReTweetOfficial(False)
1675                     StatusText.Text = ""
1676                     Exit Sub
1677                 Case Windows.Forms.DialogResult.Cancel
1678                     Exit Sub
1679             End Select
1680         End If
1681
1682         _history(_history.Count - 1) = New PostingStatus(StatusText.Text.Trim, _reply_to_id, _reply_to_name)
1683
1684         If SettingDialog.UrlConvertAuto Then
1685             StatusText.SelectionStart = StatusText.Text.Length
1686             UrlConvertAutoToolStripMenuItem_Click(Nothing, Nothing)
1687         ElseIf SettingDialog.Nicoms Then
1688             StatusText.SelectionStart = StatusText.Text.Length
1689             UrlConvert(UrlConverter.Nicoms)
1690         End If
1691         StatusText.SelectionStart = StatusText.Text.Length
1692         Dim args As New GetWorkerArg()
1693         args.page = 0
1694         args.endPage = 0
1695         args.type = WORKERTYPE.PostMessage
1696         CheckReplyTo(StatusText.Text)
1697
1698         '整形によって増加する文字数を取得
1699         Dim adjustCount As Integer = 0
1700         Dim tmpStatus As String = StatusText.Text.Trim
1701         If ToolStripMenuItemApiCommandEvasion.Checked Then
1702             ' APIコマンド回避
1703             If Regex.IsMatch(tmpStatus, _
1704                 "^[+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]*(get|g|fav|follow|f|on|off|stop|quit|leave|l|whois|w|nudge|n|stats|invite|track|untrack|tracks|tracking|\*)([+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]+|$)", _
1705                 RegexOptions.IgnoreCase) _
1706                AndAlso tmpStatus.EndsWith(" .") = False Then adjustCount += 2
1707         End If
1708
1709         If ToolStripMenuItemUrlMultibyteSplit.Checked Then
1710             ' URLと全角文字の切り離し
1711             adjustCount += Regex.Matches(tmpStatus, "https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#^]+").Count
1712         End If
1713
1714         Dim isCutOff As Boolean = False
1715         Dim isRemoveFooter As Boolean = My.Computer.Keyboard.ShiftKeyDown
1716         If StatusText.Multiline AndAlso Not SettingDialog.PostCtrlEnter Then
1717             '複数行でEnter投稿の場合、Ctrlも押されていたらフッタ付加しない
1718             isRemoveFooter = My.Computer.Keyboard.CtrlKeyDown
1719         End If
1720         If SettingDialog.PostShiftEnter Then
1721             isRemoveFooter = My.Computer.Keyboard.CtrlKeyDown
1722         End If
1723         If Not isRemoveFooter AndAlso (StatusText.Text.Contains("RT @") OrElse StatusText.Text.Contains("QT @")) Then
1724             isRemoveFooter = True
1725         End If
1726         If GetRestStatusCount(False, Not isRemoveFooter) - adjustCount < 0 Then
1727             If MessageBox.Show(My.Resources.PostLengthOverMessage1, My.Resources.PostLengthOverMessage2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.OK Then
1728                 isCutOff = True
1729                 If Not SettingDialog.UrlConvertAuto Then UrlConvertAutoToolStripMenuItem_Click(Nothing, Nothing)
1730                 If GetRestStatusCount(False, Not isRemoveFooter) - adjustCount < 0 Then
1731                     isRemoveFooter = True
1732                 End If
1733             Else
1734                 Exit Sub
1735             End If
1736         End If
1737
1738         Dim footer As String = ""
1739         Dim header As String = ""
1740         If StatusText.Text.StartsWith("D ") OrElse StatusText.Text.StartsWith("d ") Then
1741             'DM時は何もつけない
1742             footer = ""
1743         Else
1744             'ハッシュタグ
1745             If HashMgr.UseHash <> "" Then
1746                 If HashMgr.IsHead Then
1747                     header = HashMgr.UseHash + " "
1748                 Else
1749                     footer = " " + HashMgr.UseHash
1750                 End If
1751             End If
1752             If Not isRemoveFooter Then
1753                 If SettingDialog.UseRecommendStatus Then
1754                     ' 推奨ステータスを使用する
1755                     footer += SettingDialog.RecommendStatusText
1756                 Else
1757                     ' テキストボックスに入力されている文字列を使用する
1758                     footer += " " + SettingDialog.Status.Trim
1759                 End If
1760             End If
1761         End If
1762         args.status.status = header + StatusText.Text.Trim + footer
1763
1764         If ToolStripMenuItemApiCommandEvasion.Checked Then
1765             ' APIコマンド回避
1766             If Regex.IsMatch(args.status.status, _
1767                 "^[+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]*(get|g|fav|follow|f|on|off|stop|quit|leave|l|whois|w|nudge|n|stats|invite|track|untrack|tracks|tracking|\*)([+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]+|$)", _
1768                 RegexOptions.IgnoreCase) _
1769                AndAlso args.status.status.EndsWith(" .") = False Then args.status.status += " ."
1770         End If
1771
1772         If ToolStripMenuItemUrlMultibyteSplit.Checked Then
1773             ' URLと全角文字の切り離し
1774             Dim mc2 As Match = Regex.Match(args.status.status, "https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#^]+")
1775             If mc2.Success Then args.status.status = Regex.Replace(args.status.status, "https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#^]+", "$& ")
1776         End If
1777
1778         If IdeographicSpaceToSpaceToolStripMenuItem.Checked Then
1779             ' 文中の全角スペースを半角スペース1個にする
1780             args.status.status = args.status.status.Replace(" ", " ")
1781         End If
1782
1783         If isCutOff AndAlso args.status.status.Length > 140 Then
1784             args.status.status = args.status.status.Substring(0, 140)
1785             Dim AtId As String = "(@|@)[a-z0-9_/]+$"
1786             Dim HashTag As String = "(^|[^0-9A-Z&\/\?]+)(#|#)([0-9A-Z_]*[A-Z_]+)$"
1787             Dim Url As String = "https?:\/\/[a-z0-9!\*'\(\);:&=\+\$\/%#\[\]\-_\.,~?]+$" '簡易判定
1788             Dim pattern As String = String.Format("({0})|({1})|({2})", AtId, HashTag, Url)
1789             Dim mc As Match = Regex.Match(args.status.status, pattern, RegexOptions.IgnoreCase)
1790             If mc.Success Then
1791                 'さらに@ID、ハッシュタグ、URLと推測される文字列をカットする
1792                 args.status.status = args.status.status.Substring(0, 140 - mc.Value.Length)
1793             End If
1794             If MessageBox.Show(args.status.status, "Post or Cancel?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then Exit Sub
1795         End If
1796
1797         args.status.inReplyToId = _reply_to_id
1798         args.status.inReplyToName = _reply_to_name
1799         If ImageSelectionPanel.Visible Then
1800             '画像投稿
1801             If ImageSelectedPicture.Image IsNot ImageSelectedPicture.InitialImage AndAlso _
1802                 ImageServiceCombo.SelectedIndex > -1 AndAlso _
1803                 ImagefilePathText.Text <> "" Then
1804                 If MessageBox.Show(My.Resources.PostPictureConfirm1, _
1805                                    My.Resources.PostPictureConfirm2, _
1806                                    MessageBoxButtons.OKCancel, _
1807                                    MessageBoxIcon.Question, _
1808                                    MessageBoxDefaultButton.Button1) _
1809                                = Windows.Forms.DialogResult.Cancel Then
1810                     TimelinePanel.Visible = True
1811                     TimelinePanel.Enabled = True
1812                     ImageSelectionPanel.Visible = False
1813                     ImageSelectionPanel.Enabled = False
1814                     If _curList IsNot Nothing Then
1815                         _curList.Focus()
1816                     End If
1817                     Exit Sub
1818                 End If
1819                 args.status.imageService = ImageServiceCombo.Text
1820                 args.status.imagePath = ImagefilePathText.Text
1821                 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
1822                 ImagefilePathText.Text = ""
1823                 TimelinePanel.Visible = True
1824                 TimelinePanel.Enabled = True
1825                 ImageSelectionPanel.Visible = False
1826                 ImageSelectionPanel.Enabled = False
1827                 If _curList IsNot Nothing Then
1828                     _curList.Focus()
1829                 End If
1830             Else
1831                 MessageBox.Show(My.Resources.PostPictureWarn1, My.Resources.PostPictureWarn2)
1832                 Exit Sub
1833             End If
1834         End If
1835
1836         RunAsync(args)
1837
1838         'Google検索(試験実装)
1839         If StatusText.Text.StartsWith("Google:", StringComparison.OrdinalIgnoreCase) AndAlso StatusText.Text.Trim.Length > 7 Then
1840             Dim tmp As String = String.Format(My.Resources.SearchItem2Url, HttpUtility.UrlEncode(StatusText.Text.Substring(7)))
1841             OpenUriAsync(tmp)
1842         End If
1843
1844         _reply_to_id = 0
1845         _reply_to_name = ""
1846         StatusText.Text = ""
1847         _history.Add(New PostingStatus)
1848         _hisIdx = _history.Count - 1
1849         If Not ToolStripFocusLockMenuItem.Checked Then
1850             DirectCast(ListTab.SelectedTab.Tag, Control).Focus()
1851         End If
1852         urlUndoBuffer = Nothing
1853         UrlUndoToolStripMenuItem.Enabled = False  'Undoをできないように設定
1854     End Sub
1855
1856     Private Sub EndToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles EndToolStripMenuItem.Click, EndFileMenuItem.Click
1857         _endingFlag = True
1858         Me.Close()
1859     End Sub
1860
1861     Private Sub Tween_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
1862         If Not SettingDialog.CloseToExit AndAlso e.CloseReason = CloseReason.UserClosing AndAlso _endingFlag = False Then
1863             '_endingFlag=False:フォームの×ボタン
1864             e.Cancel = True
1865             Me.Visible = False
1866         Else
1867             _hookGlobalHotkey.UnregisterAllOriginalHotkey()
1868             _ignoreConfigSave = True
1869             _endingFlag = True
1870             TimerTimeline.Enabled = False
1871             TimerRefreshIcon.Enabled = False
1872         End If
1873     End Sub
1874
1875     Private Sub NotifyIcon1_BalloonTipClicked(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NotifyIcon1.BalloonTipClicked
1876         Me.Visible = True
1877         If Me.WindowState = FormWindowState.Minimized Then
1878             Me.WindowState = FormWindowState.Normal
1879         End If
1880         Me.Activate()
1881     End Sub
1882
1883     Private Shared Function CheckAccountValid() As Boolean
1884         Static errorCount As Integer = 0
1885         If Twitter.AccountState <> ACCOUNT_STATE.Valid Then
1886             errorCount += 1
1887             If errorCount > 5 Then
1888                 errorCount = 0
1889                 Twitter.AccountState = ACCOUNT_STATE.Valid
1890                 Return True
1891             End If
1892             Return False
1893         End If
1894         errorCount = 0
1895         Return True
1896     End Function
1897
1898     Private Sub GetTimelineWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
1899         Dim bw As BackgroundWorker = DirectCast(sender, BackgroundWorker)
1900         If bw.CancellationPending OrElse _endingFlag Then
1901             e.Cancel = True
1902             Exit Sub
1903         End If
1904
1905         Threading.Thread.CurrentThread.Priority = Threading.ThreadPriority.BelowNormal
1906
1907         My.Application.InitCulture()
1908
1909         Dim ret As String = ""
1910         Dim rslt As New GetWorkerResult()
1911
1912         Dim read As Boolean = Not SettingDialog.UnreadManage
1913         If _initial AndAlso SettingDialog.UnreadManage Then read = SettingDialog.Readed
1914
1915         Dim args As GetWorkerArg = DirectCast(e.Argument, GetWorkerArg)
1916
1917         If Not CheckAccountValid() Then
1918             rslt.retMsg = "Auth error. Check your account"
1919             rslt.type = WORKERTYPE.ErrorState  'エラー表示のみ行ない、後処理キャンセル
1920             rslt.tName = args.tName
1921             e.Result = rslt
1922             Exit Sub
1923         End If
1924
1925         If args.type <> WORKERTYPE.OpenUri Then bw.ReportProgress(0, "") 'Notifyアイコンアニメーション開始
1926         Select Case args.type
1927             Case WORKERTYPE.Timeline, WORKERTYPE.Reply
1928                 bw.ReportProgress(50, MakeStatusMessage(args, False))
1929                 ret = tw.GetTimelineApi(read, args.type, args.page = -1, _initial)
1930                 '新着時未読クリア
1931                 If ret = "" AndAlso args.type = WORKERTYPE.Timeline AndAlso SettingDialog.ReadOldPosts Then
1932                     _statuses.SetRead()
1933                 End If
1934                 '振り分け
1935                 rslt.addCount = _statuses.DistributePosts()
1936             Case WORKERTYPE.DirectMessegeRcv    '送信分もまとめて取得
1937                 bw.ReportProgress(50, MakeStatusMessage(args, False))
1938                 ret = tw.GetDirectMessageApi(read, WORKERTYPE.DirectMessegeRcv, args.page = -1)
1939                 If ret = "" Then ret = tw.GetDirectMessageApi(read, WORKERTYPE.DirectMessegeSnt, args.page = -1)
1940                 rslt.addCount = _statuses.DistributePosts()
1941             Case WORKERTYPE.FavAdd
1942                 'スレッド処理はしない
1943                 If _statuses.Tabs.ContainsKey(args.tName) Then
1944                     Dim tbc As TabClass = _statuses.Tabs(args.tName)
1945                     For i As Integer = 0 To args.ids.Count - 1
1946                         Dim post As PostClass = Nothing
1947                         If tbc.IsInnerStorageTabType Then
1948                             post = tbc.Posts(args.ids(i))
1949                         Else
1950                             post = _statuses.Item(args.ids(i))
1951                         End If
1952                         args.page = i + 1
1953                         bw.ReportProgress(50, MakeStatusMessage(args, False))
1954                         If Not post.IsFav Then
1955                             If post.RetweetedId = 0 Then
1956                                 ret = tw.PostFavAdd(post.StatusId)
1957                             Else
1958                                 ret = tw.PostFavAdd(post.RetweetedId)
1959                             End If
1960                             If ret.Length = 0 Then
1961                                 args.sIds.Add(post.StatusId)
1962                                 post.IsFav = True    'リスト再描画必要
1963                                 _favTimestamps.Add(Now)
1964                                 If post.RelTabName = "" Then
1965                                     '検索,リストUserTimeline.Relatedタブからのfavは、favタブへ追加せず。それ以外は追加
1966                                     _statuses.GetTabByType(TabUsageType.Favorites).Add(post.StatusId, post.IsRead, False)
1967                                 Else
1968                                     '検索,リスト,UserTimeline.Relatedタブからのfavで、TLでも取得済みならfav反映
1969                                     If _statuses.ContainsKey(post.StatusId) Then
1970                                         Dim postTl As PostClass = _statuses.Item(post.StatusId)
1971                                         postTl.IsFav = True
1972                                         _statuses.GetTabByType(TabUsageType.Favorites).Add(postTl.StatusId, postTl.IsRead, False)
1973                                     End If
1974                                 End If
1975                                 '検索,リスト,UserTimeline,Relatedの各タブに反映
1976                                 For Each tb As TabClass In _statuses.GetTabsByType(TabUsageType.PublicSearch Or TabUsageType.Lists Or TabUsageType.UserTimeline Or TabUsageType.Related)
1977                                     If tb.Contains(post.StatusId) Then tb.Posts(post.StatusId).IsFav = True
1978                                 Next
1979                             End If
1980                         End If
1981                     Next
1982                 End If
1983                 rslt.sIds = args.sIds
1984             Case WORKERTYPE.FavRemove
1985                 'スレッド処理はしない
1986                 If _statuses.Tabs.ContainsKey(args.tName) Then
1987                     Dim tbc As TabClass = _statuses.Tabs(args.tName)
1988                     For i As Integer = 0 To args.ids.Count - 1
1989                         Dim post As PostClass = Nothing
1990                         If tbc.IsInnerStorageTabType Then
1991                             post = tbc.Posts(args.ids(i))
1992                         Else
1993                             post = _statuses.Item(args.ids(i))
1994                         End If
1995                         args.page = i + 1
1996                         bw.ReportProgress(50, MakeStatusMessage(args, False))
1997                         If post.IsFav Then
1998                             If post.RetweetedId = 0 Then
1999                                 ret = tw.PostFavRemove(post.StatusId)
2000                             Else
2001                                 ret = tw.PostFavRemove(post.RetweetedId)
2002                             End If
2003                             If ret.Length = 0 Then
2004                                 args.sIds.Add(post.StatusId)
2005                                 post.IsFav = False    'リスト再描画必要
2006                                 If _statuses.ContainsKey(post.StatusId) Then _statuses.Item(post.StatusId).IsFav = False
2007                                 '検索,リスト,UserTimeline,Relatedの各タブに反映
2008                                 For Each tb As TabClass In _statuses.GetTabsByType(TabUsageType.PublicSearch Or TabUsageType.Lists Or TabUsageType.UserTimeline Or TabUsageType.Related)
2009                                     If tb.Contains(post.StatusId) Then tb.Posts(post.StatusId).IsFav = False
2010                                 Next
2011                             End If
2012                         End If
2013                     Next
2014                 End If
2015                 rslt.sIds = args.sIds
2016             Case WORKERTYPE.PostMessage
2017                 bw.ReportProgress(200)
2018                 If String.IsNullOrEmpty(args.status.imagePath) Then
2019                     For i As Integer = 0 To 1
2020                         ret = tw.PostStatus(args.status.status, args.status.inReplyToId)
2021                         If ret = "" OrElse _
2022                            ret.StartsWith("OK:") OrElse _
2023                            ret.StartsWith("Outputz:") OrElse _
2024                            ret.StartsWith("Warn:") OrElse _
2025                            ret = "Err:Status is a duplicate." OrElse _
2026                            args.status.status.StartsWith("D", StringComparison.OrdinalIgnoreCase) OrElse _
2027                            args.status.status.StartsWith("DM", StringComparison.OrdinalIgnoreCase) OrElse _
2028                            Twitter.AccountState <> ACCOUNT_STATE.Valid Then
2029                             Exit For
2030                         End If
2031                     Next
2032                 Else
2033                     ret = Me.pictureService(args.status.imageService).Upload(args.status.imagePath,
2034                                                                            args.status.status)
2035                 End If
2036                 bw.ReportProgress(300)
2037                 rslt.status = args.status
2038             Case WORKERTYPE.Retweet
2039                 bw.ReportProgress(200)
2040                 For i As Integer = 0 To args.ids.Count - 1
2041                     ret = tw.PostRetweet(args.ids(i), read)
2042                 Next
2043                 bw.ReportProgress(300)
2044             Case WORKERTYPE.Follower
2045                 bw.ReportProgress(50, My.Resources.UpdateFollowersMenuItem1_ClickText1)
2046                 ret = tw.GetFollowersApi()
2047             Case WORKERTYPE.OpenUri
2048                 Dim myPath As String = Convert.ToString(args.url)
2049
2050                 Try
2051                     If SettingDialog.BrowserPath <> "" Then
2052                         If SettingDialog.BrowserPath.StartsWith("""") AndAlso SettingDialog.BrowserPath.Length > 2 AndAlso SettingDialog.BrowserPath.IndexOf("""", 2) > -1 Then
2053                             Dim sep As Integer = SettingDialog.BrowserPath.IndexOf("""", 2)
2054                             Dim browserPath As String = SettingDialog.BrowserPath.Substring(1, sep - 1)
2055                             Dim arg As String = ""
2056                             If sep < SettingDialog.BrowserPath.Length - 1 Then
2057                                 arg = SettingDialog.BrowserPath.Substring(sep + 1)
2058                             End If
2059                             myPath = arg + " " + myPath
2060                             System.Diagnostics.Process.Start(browserPath, myPath)
2061                         Else
2062                             System.Diagnostics.Process.Start(SettingDialog.BrowserPath, myPath)
2063                         End If
2064                     Else
2065                         System.Diagnostics.Process.Start(myPath)
2066                     End If
2067                 Catch ex As Exception
2068                     '                MessageBox.Show("ブラウザの起動に失敗、またはタイムアウトしました。" + ex.ToString())
2069                 End Try
2070             Case WORKERTYPE.Favorites
2071                 bw.ReportProgress(50, MakeStatusMessage(args, False))
2072                 ret = tw.GetFavoritesApi(read, args.type)
2073                 rslt.addCount = _statuses.DistributePosts()
2074             Case WORKERTYPE.PublicSearch
2075                 bw.ReportProgress(50, MakeStatusMessage(args, False))
2076                 If args.tName = "" Then
2077                     For Each tb As TabClass In _statuses.GetTabsByType(TabUsageType.PublicSearch)
2078                         'If tb.SearchWords <> "" Then ret = tw.GetPhoenixSearch(read, tb, False)
2079                         If tb.SearchWords <> "" Then ret = tw.GetSearch(read, tb, False)
2080                     Next
2081                 Else
2082                     Dim tb As TabClass = _statuses.GetTabByName(args.tName)
2083                     If tb IsNot Nothing Then
2084                         'ret = tw.GetPhoenixSearch(read, tb, False)
2085                         ret = tw.GetSearch(read, tb, False)
2086                         If ret = "" AndAlso args.page = -1 Then
2087                             'ret = tw.GetPhoenixSearch(read, tb, True)
2088                             ret = tw.GetSearch(read, tb, True)
2089                         End If
2090                     End If
2091                 End If
2092                 '振り分け
2093                 rslt.addCount = _statuses.DistributePosts()
2094             Case WORKERTYPE.UserTimeline
2095                 bw.ReportProgress(50, MakeStatusMessage(args, False))
2096                 Dim count As Integer = 20
2097                 If SettingDialog.UseAdditionalCount Then count = SettingDialog.UserTimelineCountApi
2098                 If args.tName = "" Then
2099                     For Each tb As TabClass In _statuses.GetTabsByType(TabUsageType.UserTimeline)
2100                         If tb.User <> "" Then ret = tw.GetUserTimelineApi(read, count, tb.User, tb, False)
2101                     Next
2102                 Else
2103                     Dim tb As TabClass = _statuses.GetTabByName(args.tName)
2104                     If tb IsNot Nothing Then
2105                         ret = tw.GetUserTimelineApi(read, count, tb.User, tb, args.page = -1)
2106                     End If
2107                 End If
2108                 '振り分け
2109                 rslt.addCount = _statuses.DistributePosts()
2110             Case WORKERTYPE.List
2111                 bw.ReportProgress(50, MakeStatusMessage(args, False))
2112                 If args.tName = "" Then
2113                     '定期更新
2114                     For Each tb As TabClass In _statuses.GetTabsByType(TabUsageType.Lists)
2115                         If tb.ListInfo IsNot Nothing AndAlso tb.ListInfo.Id <> 0 Then ret = tw.GetListStatus(read, tb, False, _initial)
2116                     Next
2117                 Else
2118                     '手動更新(特定タブのみ更新)
2119                     Dim tb As TabClass = _statuses.GetTabByName(args.tName)
2120                     If tb IsNot Nothing Then
2121                         ret = tw.GetListStatus(read, tb, args.page = -1, _initial)
2122                     End If
2123                 End If
2124                 '振り分け
2125                 rslt.addCount = _statuses.DistributePosts()
2126             Case WORKERTYPE.Related
2127                 bw.ReportProgress(50, MakeStatusMessage(args, False))
2128                 Dim tb As TabClass = _statuses.GetTabByName(args.tName)
2129                 ret = tw.GetRelatedResult(read, tb)
2130                 rslt.addCount = _statuses.DistributePosts()
2131         End Select
2132         'キャンセル要求
2133         If bw.CancellationPending Then
2134             e.Cancel = True
2135             Exit Sub
2136         End If
2137
2138         '時速表示用
2139         If args.type = WORKERTYPE.FavAdd Then
2140             Dim oneHour As Date = Now.Subtract(New TimeSpan(1, 0, 0))
2141             For i As Integer = _favTimestamps.Count - 1 To 0 Step -1
2142                 If _favTimestamps(i).CompareTo(oneHour) < 0 Then
2143                     _favTimestamps.RemoveAt(i)
2144                 End If
2145             Next
2146         End If
2147         If args.type = WORKERTYPE.Timeline AndAlso Not _initial Then
2148             SyncLock _syncObject
2149                 Dim tm As Date = Now
2150                 If _tlTimestamps.ContainsKey(tm) Then
2151                     _tlTimestamps(tm) += rslt.addCount
2152                 Else
2153                     _tlTimestamps.Add(Now, rslt.addCount)
2154                 End If
2155                 Dim oneHour As Date = Now.Subtract(New TimeSpan(1, 0, 0))
2156                 Dim keys As New List(Of Date)
2157                 _tlCount = 0
2158                 For Each key As Date In _tlTimestamps.Keys
2159                     If key.CompareTo(oneHour) < 0 Then
2160                         keys.Add(key)
2161                     Else
2162                         _tlCount += _tlTimestamps(key)
2163                     End If
2164                 Next
2165                 For Each key As Date In keys
2166                     _tlTimestamps.Remove(key)
2167                 Next
2168                 keys.Clear()
2169             End SyncLock
2170         End If
2171
2172         '終了ステータス
2173         If args.type <> WORKERTYPE.OpenUri Then bw.ReportProgress(100, MakeStatusMessage(args, True)) 'ステータス書き換え、Notifyアイコンアニメーション開始
2174
2175         rslt.retMsg = ret
2176         rslt.type = args.type
2177         rslt.tName = args.tName
2178         If args.type = WORKERTYPE.DirectMessegeRcv OrElse _
2179            args.type = WORKERTYPE.DirectMessegeSnt OrElse _
2180            args.type = WORKERTYPE.Reply OrElse _
2181            args.type = WORKERTYPE.Timeline OrElse _
2182            args.type = WORKERTYPE.Favorites Then
2183             rslt.page = args.page - 1   '値が正しいか後でチェック。10ページ毎の継続確認
2184         End If
2185
2186         e.Result = rslt
2187     End Sub
2188
2189     Private Function MakeStatusMessage(ByVal AsyncArg As GetWorkerArg, ByVal Finish As Boolean) As String
2190         Dim smsg As String = ""
2191         If Not Finish Then
2192             '継続中メッセージ
2193             Select Case AsyncArg.type
2194                 Case WORKERTYPE.Timeline
2195                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText5 + AsyncArg.page.ToString() + My.Resources.GetTimelineWorker_RunWorkerCompletedText6
2196                 Case WORKERTYPE.Reply
2197                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText4 + AsyncArg.page.ToString() + My.Resources.GetTimelineWorker_RunWorkerCompletedText6
2198                 Case WORKERTYPE.DirectMessegeRcv
2199                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText8 + AsyncArg.page.ToString() + My.Resources.GetTimelineWorker_RunWorkerCompletedText6
2200                 Case WORKERTYPE.FavAdd
2201                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText15 + AsyncArg.page.ToString() + "/" + AsyncArg.ids.Count.ToString() + _
2202                                         My.Resources.GetTimelineWorker_RunWorkerCompletedText16 + (AsyncArg.page - AsyncArg.sIds.Count - 1).ToString()
2203                 Case WORKERTYPE.FavRemove
2204                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText17 + AsyncArg.page.ToString() + "/" + AsyncArg.ids.Count.ToString() + _
2205                                         My.Resources.GetTimelineWorker_RunWorkerCompletedText18 + (AsyncArg.page - AsyncArg.sIds.Count - 1).ToString()
2206                 Case WORKERTYPE.Favorites
2207                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText19
2208                 Case WORKERTYPE.PublicSearch
2209                     smsg = "Search refreshing..."
2210                 Case WORKERTYPE.List
2211                     smsg = "List refreshing..."
2212                 Case WORKERTYPE.Related
2213                     smsg = "Related refreshing..."
2214                 Case WORKERTYPE.UserTimeline
2215                     smsg = "UserTimeline refreshing..."
2216             End Select
2217         Else
2218             '完了メッセージ
2219             Select Case AsyncArg.type
2220                 Case WORKERTYPE.Timeline
2221                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText1
2222                 Case WORKERTYPE.Reply
2223                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText9
2224                 Case WORKERTYPE.DirectMessegeRcv
2225                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText11
2226                 Case WORKERTYPE.DirectMessegeSnt
2227                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText13
2228                 Case WORKERTYPE.FavAdd
2229                     '進捗メッセージ残す
2230                 Case WORKERTYPE.FavRemove
2231                     '進捗メッセージ残す
2232                 Case WORKERTYPE.Favorites
2233                     smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText20
2234                 Case WORKERTYPE.Follower
2235                     smsg = My.Resources.UpdateFollowersMenuItem1_ClickText3
2236                 Case WORKERTYPE.PublicSearch
2237                     smsg = "Search refreshed"
2238                 Case WORKERTYPE.List
2239                     smsg = "List refreshed"
2240                 Case WORKERTYPE.Related
2241                     smsg = "Related refreshed"
2242                 Case WORKERTYPE.UserTimeline
2243                     smsg = "UserTimeline refreshed"
2244             End Select
2245         End If
2246         Return smsg
2247     End Function
2248
2249     Private Sub GetTimelineWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs)
2250         If _endingFlag Then Exit Sub
2251         If e.ProgressPercentage > 100 Then
2252             '発言投稿
2253             If e.ProgressPercentage = 200 Then    '開始
2254                 StatusLabel.Text = "Posting..."
2255             End If
2256             If e.ProgressPercentage = 300 Then  '終了
2257                 StatusLabel.Text = My.Resources.PostWorker_RunWorkerCompletedText4
2258             End If
2259         Else
2260             Dim smsg As String = DirectCast(e.UserState, String)
2261             If smsg.Length > 0 Then StatusLabel.Text = smsg
2262         End If
2263     End Sub
2264
2265     Private Sub GetTimelineWorker_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
2266
2267         If _endingFlag OrElse e.Cancelled Then Exit Sub 'キャンセル
2268
2269         If e.Error IsNot Nothing Then
2270             _myStatusError = True
2271             _waitTimeline = False
2272             _waitReply = False
2273             _waitDm = False
2274             _waitFav = False
2275             _waitPubSearch = False
2276             _waitUserTimeline = False
2277             _waitLists = False
2278             Throw New Exception("BackgroundWorker Exception", e.Error)
2279             Exit Sub
2280         End If
2281
2282         Dim rslt As GetWorkerResult = DirectCast(e.Result, GetWorkerResult)
2283
2284         If rslt.type = WORKERTYPE.OpenUri Then Exit Sub
2285
2286         'エラー
2287         If rslt.retMsg.Length > 0 Then
2288             _myStatusError = True
2289             StatusLabel.Text = rslt.retMsg
2290         End If
2291
2292         If rslt.type = WORKERTYPE.ErrorState Then Exit Sub
2293
2294         If rslt.type = WORKERTYPE.FavRemove Then
2295             Me.RemovePostFromFavTab(rslt.sIds.ToArray)
2296         End If
2297
2298         'リストに反映
2299         'Dim busy As Boolean = False
2300         'For Each bw As BackgroundWorker In _bw
2301         '    If bw IsNot Nothing AndAlso bw.IsBusy Then
2302         '        busy = True
2303         '        Exit For
2304         '    End If
2305         'Next
2306         'If Not busy Then RefreshTimeline() 'background処理なければ、リスト反映
2307         If rslt.type = WORKERTYPE.Timeline OrElse _
2308            rslt.type = WORKERTYPE.Reply OrElse _
2309            rslt.type = WORKERTYPE.List OrElse _
2310            rslt.type = WORKERTYPE.PublicSearch OrElse _
2311            rslt.type = WORKERTYPE.DirectMessegeRcv OrElse _
2312            rslt.type = WORKERTYPE.DirectMessegeSnt OrElse _
2313            rslt.type = WORKERTYPE.Favorites OrElse _
2314            rslt.type = WORKERTYPE.Follower OrElse _
2315            rslt.type = WORKERTYPE.FavAdd OrElse _
2316            rslt.type = WORKERTYPE.FavRemove OrElse _
2317            rslt.type = WORKERTYPE.Related OrElse _
2318            rslt.type = WORKERTYPE.UserTimeline Then
2319             RefreshTimeline(False) 'リスト反映
2320         End If
2321
2322         Select Case rslt.type
2323             Case WORKERTYPE.Timeline
2324                 _waitTimeline = False
2325                 If Not _initial Then
2326                     '    'API使用時の取得調整は別途考える(カウント調整?)
2327                 End If
2328             Case WORKERTYPE.Reply
2329                 _waitReply = False
2330                 If rslt.newDM AndAlso Not _initial Then
2331                     GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0, "")
2332                 End If
2333             Case WORKERTYPE.Favorites
2334                 _waitFav = False
2335             Case WORKERTYPE.DirectMessegeRcv
2336                 _waitDm = False
2337             Case WORKERTYPE.FavAdd, WORKERTYPE.FavRemove
2338                 If _curList IsNot Nothing AndAlso _curTab IsNot Nothing Then
2339                     _curList.BeginUpdate()
2340                     If rslt.type = WORKERTYPE.FavRemove AndAlso _statuses.Tabs(_curTab.Text).TabType = TabUsageType.Favorites Then
2341                         '色変えは不要
2342                     Else
2343                         For i As Integer = 0 To rslt.sIds.Count - 1
2344                             If _curTab.Text.Equals(rslt.tName) Then
2345                                 Dim idx As Integer = _statuses.Tabs(rslt.tName).IndexOf(rslt.sIds(i))
2346                                 If idx > -1 Then
2347                                     Dim post As PostClass = Nothing
2348                                     Dim tb As TabClass = _statuses.Tabs(rslt.tName)
2349                                     If tb IsNot Nothing Then
2350                                         If tb.TabType = TabUsageType.Lists OrElse tb.TabType = TabUsageType.PublicSearch Then
2351                                             post = tb.Posts(rslt.sIds(i))
2352                                         Else
2353                                             post = _statuses.Item(rslt.sIds(i))
2354                                         End If
2355                                         ChangeCacheStyleRead(post.IsRead, idx, _curTab)
2356                                     End If
2357                                     If idx = _curItemIndex Then DispSelectedPost(True) '選択アイテム再表示
2358                                 End If
2359                             End If
2360                         Next
2361                     End If
2362                     _curList.EndUpdate()
2363                 End If
2364             Case WORKERTYPE.PostMessage
2365                 If rslt.retMsg = "" OrElse _
2366                     rslt.retMsg.StartsWith("Outputz") OrElse _
2367                     rslt.retMsg.StartsWith("OK:") OrElse _
2368                     rslt.retMsg = "Warn:Status is a duplicate." Then
2369                     _postTimestamps.Add(Now)
2370                     Dim oneHour As Date = Now.Subtract(New TimeSpan(1, 0, 0))
2371                     For i As Integer = _postTimestamps.Count - 1 To 0 Step -1
2372                         If _postTimestamps(i).CompareTo(oneHour) < 0 Then
2373                             _postTimestamps.RemoveAt(i)
2374                         End If
2375                     Next
2376
2377                     If Not HashMgr.IsPermanent AndAlso HashMgr.UseHash <> "" Then
2378                         HashMgr.ClearHashtag()
2379                         Me.HashStripSplitButton.Text = "#[-]"
2380                         Me.HashToggleMenuItem.Checked = False
2381                         Me.HashToggleToolStripMenuItem.Checked = False
2382                     End If
2383                     SetMainWindowTitle()
2384                     rslt.retMsg = ""
2385                 Else
2386                     Dim retry As DialogResult
2387                     Try
2388                         retry = MessageBox.Show(String.Format("{0}   --->   [ " & rslt.retMsg & " ]" & Environment.NewLine & """" & rslt.status.status & """" & Environment.NewLine & "{1}",
2389                                                             My.Resources.StatusUpdateFailed1,
2390                                                             My.Resources.StatusUpdateFailed2),
2391                                                         "Failed to update status",
2392                                                         MessageBoxButtons.RetryCancel,
2393                                                         MessageBoxIcon.Question)
2394                     Catch ex As Exception
2395                         retry = Windows.Forms.DialogResult.Abort
2396                     End Try
2397                     If retry = Windows.Forms.DialogResult.Retry Then
2398                         Dim args As New GetWorkerArg()
2399                         args.page = 0
2400                         args.endPage = 0
2401                         args.type = WORKERTYPE.PostMessage
2402                         args.status = rslt.status
2403                         RunAsync(args)
2404                     Else
2405                         If ToolStripFocusLockMenuItem.Checked Then
2406                             '連投モードのときだけEnterイベントが起きないので強制的に背景色を戻す
2407                             StatusText_Enter(StatusText, New EventArgs)
2408                         End If
2409                     End If
2410                 End If
2411                 If rslt.retMsg.Length = 0 AndAlso SettingDialog.PostAndGet Then GetTimeline(WORKERTYPE.Timeline, 1, 0, "")
2412             Case WORKERTYPE.Retweet
2413                 If rslt.retMsg.Length = 0 Then
2414                     _postTimestamps.Add(Now)
2415                     Dim oneHour As Date = Now.Subtract(New TimeSpan(1, 0, 0))
2416                     For i As Integer = _postTimestamps.Count - 1 To 0 Step -1
2417                         If _postTimestamps(i).CompareTo(oneHour) < 0 Then
2418                             _postTimestamps.RemoveAt(i)
2419                         End If
2420                     Next
2421                     If Not _isActiveUserstream AndAlso SettingDialog.PostAndGet Then GetTimeline(WORKERTYPE.Timeline, 1, 0, "")
2422                 End If
2423             Case WORKERTYPE.Follower
2424                 '_waitFollower = False
2425                 _itemCache = Nothing
2426                 _postCache = Nothing
2427                 If _curList IsNot Nothing Then _curList.Refresh()
2428             Case WORKERTYPE.PublicSearch
2429                 _waitPubSearch = False
2430             Case WORKERTYPE.UserTimeline
2431                 _waitUserTimeline = False
2432             Case WORKERTYPE.List
2433                 _waitLists = False
2434             Case WORKERTYPE.Related
2435                 Dim tb As TabClass = _statuses.GetTabByType(TabUsageType.Related)
2436                 If tb IsNot Nothing AndAlso tb.RelationTargetPost IsNot Nothing AndAlso tb.Contains(tb.RelationTargetPost.StatusId) Then
2437                     For Each tp As TabPage In ListTab.TabPages
2438                         If tp.Text = tb.TabName Then
2439                             DirectCast(tp.Tag, DetailsListView).SelectedIndices.Add(tb.IndexOf(tb.RelationTargetPost.StatusId))
2440                             DirectCast(tp.Tag, DetailsListView).Items(tb.IndexOf(tb.RelationTargetPost.StatusId)).Focused = True
2441                             Exit For
2442                         End If
2443                     Next
2444                 End If
2445         End Select
2446
2447     End Sub
2448
2449     Private Sub RemovePostFromFavTab(ByVal ids As Int64())
2450         Dim favTabName As String = _statuses.GetTabByType(TabUsageType.Favorites).TabName
2451         Dim fidx As Integer
2452         If _curTab.Text.Equals(favTabName) Then
2453             If _curList.FocusedItem IsNot Nothing Then
2454                 fidx = _curList.FocusedItem.Index
2455             ElseIf _curList.TopItem IsNot Nothing Then
2456                 fidx = _curList.TopItem.Index
2457             Else
2458                 fidx = 0
2459             End If
2460         End If
2461
2462         For Each i As Long In ids
2463             _statuses.RemoveFavPost(i)
2464         Next
2465         If _curTab IsNot Nothing AndAlso _curTab.Text.Equals(favTabName) Then
2466             _itemCache = Nothing    'キャッシュ破棄
2467             _postCache = Nothing
2468             _curPost = Nothing
2469             '_curItemIndex = -1
2470         End If
2471         For Each tp As TabPage In ListTab.TabPages
2472             If tp.Text = favTabName Then
2473                 DirectCast(tp.Tag, DetailsListView).VirtualListSize = _statuses.Tabs(favTabName).AllCount
2474                 Exit For
2475             End If
2476         Next
2477         If _curTab.Text.Equals(favTabName) Then
2478             Do
2479                 _curList.SelectedIndices.Clear()
2480             Loop While _curList.SelectedIndices.Count > 0
2481             If _statuses.Tabs(favTabName).AllCount > 0 Then
2482                 If _statuses.Tabs(favTabName).AllCount - 1 > fidx AndAlso fidx > -1 Then
2483                     _curList.SelectedIndices.Add(fidx)
2484                 Else
2485                     _curList.SelectedIndices.Add(_statuses.Tabs(favTabName).AllCount - 1)
2486                 End If
2487                 If _curList.SelectedIndices.Count > 0 Then
2488                     _curList.EnsureVisible(_curList.SelectedIndices(0))
2489                     _curList.FocusedItem = _curList.Items(_curList.SelectedIndices(0))
2490                 End If
2491             End If
2492         End If
2493
2494     End Sub
2495     Private Sub GetTimeline(ByVal WkType As WORKERTYPE, ByVal fromPage As Integer, ByVal toPage As Integer, ByVal tabName As String)
2496
2497         If Not IsNetworkAvailable() Then Exit Sub
2498
2499         '非同期実行引数設定
2500         Dim args As New GetWorkerArg
2501         args.page = fromPage
2502         args.endPage = toPage
2503         args.type = WkType
2504         args.tName = tabName
2505
2506         Static lastTime As New Dictionary(Of WORKERTYPE, DateTime)
2507         If Not lastTime.ContainsKey(WkType) Then lastTime.Add(WkType, New DateTime)
2508         Dim period As Double = Now.Subtract(lastTime(WkType)).TotalSeconds
2509         If period > 1 OrElse period < -1 Then
2510             lastTime(WkType) = Now
2511             RunAsync(args)
2512         End If
2513
2514         'Timeline取得モードの場合はReplyも同時に取得
2515         'If Not SettingDialog.UseAPI AndAlso _
2516         '   Not _initial AndAlso _
2517         '   WkType = WORKERTYPE.Timeline AndAlso _
2518         '   SettingDialog.CheckReply Then
2519         '    'TimerReply.Enabled = False
2520         '    _mentionCounter = SettingDialog.ReplyPeriodInt
2521         '    Dim _args As New GetWorkerArg
2522         '    _args.page = fromPage
2523         '    _args.endPage = toPage
2524         '    _args.type = WORKERTYPE.Reply
2525         '    RunAsync(_args)
2526         'End If
2527     End Sub
2528
2529     Private Sub NotifyIcon1_MouseClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.MouseClick
2530         If e.Button = Windows.Forms.MouseButtons.Left Then
2531             Me.Visible = True
2532             If Me.WindowState = FormWindowState.Minimized Then
2533                 Me.WindowState = FormWindowState.Normal
2534             End If
2535             Me.Activate()
2536         End If
2537     End Sub
2538
2539     Private Sub MyList_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
2540         MakeReplyOrDirectStatus()
2541     End Sub
2542
2543     Private Sub FavAddToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FavAddToolStripMenuItem.Click, FavOpMenuItem.Click
2544         FavoriteChange(True)
2545     End Sub
2546
2547     Private Sub FavRemoveToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FavRemoveToolStripMenuItem.Click, UnFavOpMenuItem.Click
2548         FavoriteChange(False)
2549     End Sub
2550
2551
2552     Private Sub FavoriteRetweetMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FavoriteRetweetMenuItem.Click, FavoriteRetweetContextMenu.Click
2553         FavoritesRetweetOriginal()
2554     End Sub
2555
2556     Private Sub FavoriteRetweetUnofficialMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FavoriteRetweetUnofficialMenuItem.Click, FavoriteRetweetUnofficialContextMenu.Click
2557         FavoritesRetweetUnofficial()
2558     End Sub
2559
2560     Private Sub FavoriteChange(ByVal FavAdd As Boolean, Optional ByVal multiFavoriteChangeDialogEnable As Boolean = True)
2561         'TrueでFavAdd,FalseでFavRemove
2562         If _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage OrElse _curList.SelectedIndices.Count = 0 _
2563             OrElse Not Me.ExistCurrentPost Then Exit Sub
2564
2565         '複数fav確認msg
2566         If _curList.SelectedIndices.Count > 250 AndAlso FavAdd Then
2567             MessageBox.Show(My.Resources.FavoriteLimitCountText)
2568             _DoFavRetweetFlags = False
2569             Exit Sub
2570         ElseIf multiFavoriteChangeDialogEnable AndAlso _curList.SelectedIndices.Count > 1 Then
2571             If FavAdd Then
2572                 Dim QuestionText As String = My.Resources.FavAddToolStripMenuItem_ClickText1
2573                 If _DoFavRetweetFlags Then QuestionText = My.Resources.FavoriteRetweetQuestionText3
2574                 If MessageBox.Show(QuestionText, My.Resources.FavAddToolStripMenuItem_ClickText2, _
2575                                    MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
2576                     _DoFavRetweetFlags = False
2577                     Exit Sub
2578                 End If
2579             Else
2580                 If MessageBox.Show(My.Resources.FavRemoveToolStripMenuItem_ClickText1, My.Resources.FavRemoveToolStripMenuItem_ClickText2, _
2581                                 MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
2582                     Exit Sub
2583                 End If
2584             End If
2585         End If
2586
2587         Dim args As New GetWorkerArg
2588         args.ids = New List(Of Long)
2589         args.sIds = New List(Of Long)
2590         args.tName = _curTab.Text
2591         If FavAdd Then
2592             args.type = WORKERTYPE.FavAdd
2593         Else
2594             args.type = WORKERTYPE.FavRemove
2595         End If
2596         For Each idx As Integer In _curList.SelectedIndices
2597             Dim post As PostClass = GetCurTabPost(idx)
2598             If FavAdd Then
2599                 If Not post.IsFav Then args.ids.Add(post.StatusId)
2600             Else
2601                 If post.IsFav Then args.ids.Add(post.StatusId)
2602             End If
2603         Next
2604         If args.ids.Count = 0 Then
2605             If FavAdd Then
2606                 StatusLabel.Text = My.Resources.FavAddToolStripMenuItem_ClickText4
2607             Else
2608                 StatusLabel.Text = My.Resources.FavRemoveToolStripMenuItem_ClickText4
2609             End If
2610             Exit Sub
2611         End If
2612
2613         RunAsync(args)
2614     End Sub
2615
2616     Private Function GetCurTabPost(ByVal Index As Integer) As PostClass
2617         If _postCache IsNot Nothing AndAlso Index >= _itemCacheIndex AndAlso Index < _itemCacheIndex + _postCache.Length Then
2618             Return _postCache(Index - _itemCacheIndex)
2619         Else
2620             Return _statuses.Item(_curTab.Text, Index)
2621         End If
2622     End Function
2623
2624
2625     Private Sub MoveToHomeToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MoveToHomeToolStripMenuItem.Click, OpenHomeOpMenuItem.Click
2626         If _curList.SelectedIndices.Count > 0 Then
2627             OpenUriAsync("http://twitter.com/" + GetCurTabPost(_curList.SelectedIndices(0)).ScreenName)
2628         ElseIf _curList.SelectedIndices.Count = 0 Then
2629             OpenUriAsync("http://twitter.com/")
2630         End If
2631     End Sub
2632
2633     Private Sub MoveToFavToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MoveToFavToolStripMenuItem.Click, OpenFavOpMenuItem.Click
2634         If _curList.SelectedIndices.Count > 0 Then
2635             OpenUriAsync("http://twitter.com/" + GetCurTabPost(_curList.SelectedIndices(0)).ScreenName + "/favorites")
2636         End If
2637     End Sub
2638
2639     Private Sub Tween_ClientSizeChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.ClientSizeChanged
2640         If (Not _initialLayout) AndAlso _
2641             Me.Visible AndAlso _
2642             Me.WindowState = FormWindowState.Normal Then
2643
2644             'Dim colNo As Integer = 2
2645             'If _iconCol Then colNo = 1
2646             'Dim widthDiff As Integer = Me.ClientSize.Width - Me._mySize.Width
2647             'Dim listView As DetailsListView = CType(Me._curTab.Tag, DetailsListView)
2648             'Dim column As ColumnHeader = listView.Columns(colNo)
2649             'column.Width += widthDiff
2650             'Me.MyList_ColumnWidthChanged(listView, New ColumnWidthChangedEventArgs(colNo))
2651
2652             _mySize = Me.ClientSize
2653             _mySpDis = Me.SplitContainer1.SplitterDistance
2654             _mySpDis3 = Me.SplitContainer3.SplitterDistance
2655             If StatusText.Multiline Then _mySpDis2 = Me.StatusText.Height
2656             _modifySettingLocal = True
2657         End If
2658     End Sub
2659
2660     Private Sub MyList_ColumnClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs)
2661         If SettingDialog.SortOrderLock Then Exit Sub
2662         Dim mode As IdComparerClass.ComparerMode
2663         If _iconCol Then
2664             mode = IdComparerClass.ComparerMode.Id
2665         Else
2666             Select Case e.Column
2667                 Case 0, 5, 6    '0:アイコン,5:未読マーク,6:プロテクト・フィルターマーク
2668                     'ソートしない
2669                     Exit Sub
2670                 Case 1  'ニックネーム
2671                     mode = IdComparerClass.ComparerMode.Nickname
2672                 Case 2  '本文
2673                     mode = IdComparerClass.ComparerMode.Data
2674                 Case 3  '時刻=発言Id
2675                     mode = IdComparerClass.ComparerMode.Id
2676                 Case 4  '名前
2677                     mode = IdComparerClass.ComparerMode.Name
2678                 Case 7  'Source
2679                     mode = IdComparerClass.ComparerMode.Source
2680             End Select
2681         End If
2682         _statuses.ToggleSortOrder(mode)
2683         InitColumnText()
2684
2685         If _iconCol Then
2686             DirectCast(sender, DetailsListView).Columns.Item(0).Text = ColumnOrgText(0)
2687             DirectCast(sender, DetailsListView).Columns.Item(1).Text = ColumnText(2)
2688         Else
2689             For i As Integer = 0 To 7
2690                 DirectCast(sender, DetailsListView).Columns.Item(i).Text = ColumnOrgText(i)
2691             Next
2692             DirectCast(sender, DetailsListView).Columns.Item(e.Column).Text = ColumnText(e.Column)
2693         End If
2694
2695         _itemCache = Nothing
2696         _postCache = Nothing
2697
2698         If _statuses.Tabs(_curTab.Text).AllCount > 0 AndAlso _curPost IsNot Nothing Then
2699             Dim idx As Integer = _statuses.Tabs(_curTab.Text).IndexOf(_curPost.StatusId)
2700             If idx > -1 Then
2701                 SelectListItem(_curList, idx)
2702                 _curList.EnsureVisible(idx)
2703             End If
2704         End If
2705         _curList.Refresh()
2706         _modifySettingCommon = True
2707     End Sub
2708
2709     Private Sub Tween_LocationChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LocationChanged
2710         If Me.WindowState = FormWindowState.Normal AndAlso Not _initialLayout Then
2711             _myLoc = Me.DesktopLocation
2712             _modifySettingLocal = True
2713         End If
2714     End Sub
2715
2716     Private Sub ContextMenuOperate_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuOperate.Opening
2717         If ListTab.SelectedTab Is Nothing Then Exit Sub
2718         If _statuses Is Nothing OrElse _statuses.Tabs Is Nothing OrElse Not _statuses.Tabs.ContainsKey(ListTab.SelectedTab.Text) Then Exit Sub
2719         If Not Me.ExistCurrentPost Then
2720             ReplyStripMenuItem.Enabled = False
2721             ReplyAllStripMenuItem.Enabled = False
2722             DMStripMenuItem.Enabled = False
2723             ShowProfileMenuItem.Enabled = False
2724             ShowUserTimelineContextMenuItem.Enabled = False
2725             ListManageUserContextToolStripMenuItem2.Enabled = False
2726             MoveToFavToolStripMenuItem.Enabled = False
2727             TabMenuItem.Enabled = False
2728             IDRuleMenuItem.Enabled = False
2729             ReadedStripMenuItem.Enabled = False
2730             UnreadStripMenuItem.Enabled = False
2731         Else
2732             ShowProfileMenuItem.Enabled = True
2733             ListManageUserContextToolStripMenuItem2.Enabled = True
2734             ReplyStripMenuItem.Enabled = True
2735             ReplyAllStripMenuItem.Enabled = True
2736             DMStripMenuItem.Enabled = True
2737             ShowUserTimelineContextMenuItem.Enabled = True
2738             MoveToFavToolStripMenuItem.Enabled = True
2739             TabMenuItem.Enabled = True
2740             IDRuleMenuItem.Enabled = True
2741             ReadedStripMenuItem.Enabled = True
2742             UnreadStripMenuItem.Enabled = True
2743         End If
2744         If _statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.DirectMessage OrElse Not Me.ExistCurrentPost OrElse _curPost.IsDm Then
2745             FavAddToolStripMenuItem.Enabled = False
2746             FavRemoveToolStripMenuItem.Enabled = False
2747             StatusOpenMenuItem.Enabled = False
2748             FavorareMenuItem.Enabled = False
2749             ShowRelatedStatusesMenuItem.Enabled = False
2750
2751             ReTweetStripMenuItem.Enabled = False
2752             ReTweetOriginalStripMenuItem.Enabled = False
2753             QuoteStripMenuItem.Enabled = False
2754             FavoriteRetweetContextMenu.Enabled = False
2755             FavoriteRetweetUnofficialContextMenu.Enabled = False
2756             If Me.ExistCurrentPost AndAlso _curPost.IsDm Then DeleteStripMenuItem.Enabled = True
2757         Else
2758             FavAddToolStripMenuItem.Enabled = True
2759             FavRemoveToolStripMenuItem.Enabled = True
2760             StatusOpenMenuItem.Enabled = True
2761             FavorareMenuItem.Enabled = True
2762             ShowRelatedStatusesMenuItem.Enabled = True  'PublicSearchの時問題出るかも
2763
2764             If _curPost.IsMe Then
2765                 ReTweetOriginalStripMenuItem.Enabled = False
2766                 FavoriteRetweetContextMenu.Enabled = False
2767                 DeleteStripMenuItem.Enabled = True
2768             Else
2769                 DeleteStripMenuItem.Enabled = False
2770                 If _curPost.IsProtect Then
2771                     ReTweetOriginalStripMenuItem.Enabled = False
2772                     ReTweetStripMenuItem.Enabled = False
2773                     QuoteStripMenuItem.Enabled = False
2774                     FavoriteRetweetContextMenu.Enabled = False
2775                     FavoriteRetweetUnofficialContextMenu.Enabled = False
2776                 Else
2777                     ReTweetOriginalStripMenuItem.Enabled = True
2778                     ReTweetStripMenuItem.Enabled = True
2779                     QuoteStripMenuItem.Enabled = True
2780                     FavoriteRetweetContextMenu.Enabled = True
2781                     FavoriteRetweetUnofficialContextMenu.Enabled = True
2782                 End If
2783             End If
2784         End If
2785         If _statuses.Tabs(ListTab.SelectedTab.Text).TabType <> TabUsageType.Favorites Then
2786             RefreshMoreStripMenuItem.Enabled = True
2787         Else
2788             RefreshMoreStripMenuItem.Enabled = False
2789         End If
2790         If _statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.PublicSearch _
2791                             OrElse Not Me.ExistCurrentPost _
2792                             OrElse Not _curPost.InReplyToStatusId > 0 Then
2793             RepliedStatusOpenMenuItem.Enabled = False
2794         Else
2795             RepliedStatusOpenMenuItem.Enabled = True
2796         End If
2797         If Not Me.ExistCurrentPost OrElse _curPost.RetweetedBy = "" Then
2798             MoveToRTHomeMenuItem.Enabled = False
2799         Else
2800             MoveToRTHomeMenuItem.Enabled = True
2801         End If
2802     End Sub
2803
2804     Private Sub ReplyStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReplyStripMenuItem.Click, ReplyOpMenuItem.Click
2805         MakeReplyOrDirectStatus(False, True)
2806     End Sub
2807
2808     Private Sub DMStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DMStripMenuItem.Click, DmOpMenuItem.Click
2809         MakeReplyOrDirectStatus(False, False)
2810     End Sub
2811
2812     Private Sub doStatusDelete()
2813         If _curTab Is Nothing OrElse _curList Is Nothing Then Exit Sub
2814         If _statuses.Tabs(_curTab.Text).TabType <> TabUsageType.DirectMessage Then
2815             Dim myPost As Boolean = False
2816             For Each idx As Integer In _curList.SelectedIndices
2817                 If GetCurTabPost(idx).IsMe OrElse _
2818                    GetCurTabPost(idx).RetweetedBy.ToLower = tw.Username.ToLower Then
2819                     myPost = True
2820                     Exit For
2821                 End If
2822             Next
2823             If Not myPost Then Exit Sub
2824         Else
2825             If _curList.SelectedIndices.Count = 0 Then
2826                 Exit Sub
2827             End If
2828         End If
2829
2830         Dim tmp As String = String.Format(My.Resources.DeleteStripMenuItem_ClickText1, Environment.NewLine)
2831
2832         If MessageBox.Show(tmp, My.Resources.DeleteStripMenuItem_ClickText2, _
2833               MessageBoxButtons.OKCancel, _
2834               MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then Exit Sub
2835
2836         Dim fidx As Integer
2837         If _curList.FocusedItem IsNot Nothing Then
2838             fidx = _curList.FocusedItem.Index
2839         ElseIf _curList.TopItem IsNot Nothing Then
2840             fidx = _curList.TopItem.Index
2841         Else
2842             fidx = 0
2843         End If
2844
2845         Try
2846             Me.Cursor = Cursors.WaitCursor
2847
2848             Dim rslt As Boolean = True
2849             For Each Id As Long In _statuses.GetId(_curTab.Text, _curList.SelectedIndices)
2850                 Dim rtn As String = ""
2851                 If _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage Then
2852                     rtn = tw.RemoveDirectMessage(Id, _statuses.Item(Id))
2853                 Else
2854                     If _statuses.Item(Id).IsMe OrElse _statuses.Item(Id).RetweetedBy.ToLower = tw.Username.ToLower Then
2855                         rtn = tw.RemoveStatus(Id)
2856                     Else
2857                         Continue For
2858                     End If
2859                 End If
2860                 If rtn.Length > 0 Then
2861                     'エラー
2862                     rslt = False
2863                 Else
2864                     _statuses.RemovePost(Id)
2865                 End If
2866             Next
2867
2868             If Not rslt Then
2869                 StatusLabel.Text = My.Resources.DeleteStripMenuItem_ClickText3  '失敗
2870             Else
2871                 StatusLabel.Text = My.Resources.DeleteStripMenuItem_ClickText4  '成功
2872             End If
2873
2874             _itemCache = Nothing    'キャッシュ破棄
2875             _postCache = Nothing
2876             _curPost = Nothing
2877             _curItemIndex = -1
2878             For Each tb As TabPage In ListTab.TabPages
2879                 DirectCast(tb.Tag, DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
2880                 If _curTab.Equals(tb) Then
2881                     Do
2882                         _curList.SelectedIndices.Clear()
2883                     Loop While _curList.SelectedIndices.Count > 0
2884                     If _statuses.Tabs(tb.Text).AllCount > 0 Then
2885                         If _statuses.Tabs(tb.Text).AllCount - 1 > fidx AndAlso fidx > -1 Then
2886                             _curList.SelectedIndices.Add(fidx)
2887                         Else
2888                             _curList.SelectedIndices.Add(_statuses.Tabs(tb.Text).AllCount - 1)
2889                         End If
2890                         If _curList.SelectedIndices.Count > 0 Then
2891                             _curList.EnsureVisible(_curList.SelectedIndices(0))
2892                             _curList.FocusedItem = _curList.Items(_curList.SelectedIndices(0))
2893                         End If
2894                     End If
2895                 End If
2896                 If _statuses.Tabs(tb.Text).UnreadCount = 0 Then
2897                     If SettingDialog.TabIconDisp Then
2898                         If tb.ImageIndex = 0 Then tb.ImageIndex = -1 'タブアイコン
2899                     End If
2900                 End If
2901             Next
2902             If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
2903         Finally
2904             Me.Cursor = Cursors.Default
2905         End Try
2906     End Sub
2907
2908     Private Sub DeleteStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DeleteStripMenuItem.Click, DelOpMenuItem.Click
2909         doStatusDelete()
2910     End Sub
2911
2912     Private Sub ReadedStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReadedStripMenuItem.Click, ReadOpMenuItem.Click
2913         _curList.BeginUpdate()
2914         If SettingDialog.UnreadManage Then
2915             For Each idx As Integer In _curList.SelectedIndices
2916                 _statuses.SetReadAllTab(True, _curTab.Text, idx)
2917             Next
2918         End If
2919         For Each idx As Integer In _curList.SelectedIndices
2920             ChangeCacheStyleRead(True, idx, _curTab)
2921         Next
2922         ColorizeList()
2923         _curList.EndUpdate()
2924         For Each tb As TabPage In ListTab.TabPages
2925             If _statuses.Tabs(tb.Text).UnreadCount = 0 Then
2926                 If SettingDialog.TabIconDisp Then
2927                     If tb.ImageIndex = 0 Then tb.ImageIndex = -1 'タブアイコン
2928                 End If
2929             End If
2930         Next
2931         If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
2932     End Sub
2933
2934     Private Sub UnreadStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UnreadStripMenuItem.Click, UnreadOpMenuItem.Click
2935         _curList.BeginUpdate()
2936         If SettingDialog.UnreadManage Then
2937             For Each idx As Integer In _curList.SelectedIndices
2938                 _statuses.SetReadAllTab(False, _curTab.Text, idx)
2939             Next
2940         End If
2941         For Each idx As Integer In _curList.SelectedIndices
2942             ChangeCacheStyleRead(False, idx, _curTab)
2943         Next
2944         ColorizeList()
2945         _curList.EndUpdate()
2946         For Each tb As TabPage In ListTab.TabPages
2947             If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
2948                 If SettingDialog.TabIconDisp Then
2949                     If tb.ImageIndex = -1 Then tb.ImageIndex = 0 'タブアイコン
2950                 End If
2951             End If
2952         Next
2953         If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
2954     End Sub
2955
2956     Private Sub RefreshStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RefreshStripMenuItem.Click, RefreshOpMenuItem.Click
2957         DoRefresh()
2958     End Sub
2959
2960     Private Sub DoRefresh()
2961         If _curTab IsNot Nothing Then
2962             Select Case _statuses.Tabs(_curTab.Text).TabType
2963                 Case TabUsageType.Mentions
2964                     GetTimeline(WORKERTYPE.Reply, 1, 0, "")
2965                 Case TabUsageType.DirectMessage
2966                     GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0, "")
2967                 Case TabUsageType.Favorites
2968                     GetTimeline(WORKERTYPE.Favorites, 1, 0, "")
2969                     'Case TabUsageType.Profile
2970                     '' TODO
2971                 Case TabUsageType.PublicSearch
2972                     '' TODO
2973                     Dim tb As TabClass = _statuses.Tabs(_curTab.Text)
2974                     If tb.SearchWords = "" Then Exit Sub
2975                     GetTimeline(WORKERTYPE.PublicSearch, 1, 0, _curTab.Text)
2976                 Case TabUsageType.UserTimeline
2977                     GetTimeline(WORKERTYPE.UserTimeline, 1, 0, _curTab.Text)
2978                 Case TabUsageType.Lists
2979                     '' TODO
2980                     Dim tb As TabClass = _statuses.Tabs(_curTab.Text)
2981                     If tb.ListInfo Is Nothing OrElse tb.ListInfo.Id = 0 Then Exit Sub
2982                     GetTimeline(WORKERTYPE.List, 1, 0, _curTab.Text)
2983                 Case Else
2984                     GetTimeline(WORKERTYPE.Timeline, 1, 0, "")
2985             End Select
2986         Else
2987             GetTimeline(WORKERTYPE.Timeline, 1, 0, "")
2988         End If
2989     End Sub
2990
2991     Private Sub DoRefreshMore()
2992         'ページ指定をマイナス1に
2993         If _curTab IsNot Nothing Then
2994             Select Case _statuses.Tabs(_curTab.Text).TabType
2995                 Case TabUsageType.Mentions
2996                     GetTimeline(WORKERTYPE.Reply, -1, 0, "")
2997                 Case TabUsageType.DirectMessage
2998                     GetTimeline(WORKERTYPE.DirectMessegeRcv, -1, 0, "")
2999                 Case TabUsageType.Favorites
3000                     '    GetTimeline(WORKERTYPE.Favorites, -1, 0, "")
3001                 Case TabUsageType.Profile
3002                     '' TODO
3003                 Case TabUsageType.PublicSearch
3004                     ' TODO
3005                     Dim tb As TabClass = _statuses.Tabs(_curTab.Text)
3006                     If tb.SearchWords = "" Then Exit Sub
3007                     GetTimeline(WORKERTYPE.PublicSearch, -1, 0, _curTab.Text)
3008                 Case TabUsageType.UserTimeline
3009                     GetTimeline(WORKERTYPE.UserTimeline, -1, 0, _curTab.Text)
3010                 Case TabUsageType.Lists
3011                     '' TODO
3012                     Dim tb As TabClass = _statuses.Tabs(_curTab.Text)
3013                     If tb.ListInfo Is Nothing OrElse tb.ListInfo.Id = 0 Then Exit Sub
3014                     GetTimeline(WORKERTYPE.List, -1, 0, _curTab.Text)
3015                 Case Else
3016                     GetTimeline(WORKERTYPE.Timeline, -1, 0, "")
3017             End Select
3018         Else
3019             GetTimeline(WORKERTYPE.Timeline, -1, 0, "")
3020         End If
3021     End Sub
3022
3023     Private Sub SettingStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SettingStripMenuItem.Click, SettingFileMenuItem.Click
3024         Dim result As DialogResult
3025         Dim uid As String = tw.Username.ToLower
3026
3027         Try
3028             result = SettingDialog.ShowDialog()
3029         Catch ex As Exception
3030             Exit Sub
3031         End Try
3032
3033         If result = Windows.Forms.DialogResult.OK Then
3034             SyncLock _syncObject
3035                 'Try
3036                 '    If SettingDialog.TimelinePeriodInt > 0 Then
3037                 '        _homeCounterAdjuster = 0
3038                 '    End If
3039                 'Catch ex As Exception
3040                 '    ex.Data("Instance") = "Set Timers"
3041                 '    ex.Data("IsTerminatePermission") = False
3042                 '    Throw
3043                 'End Try
3044                 'tw.CountApi = SettingDialog.CountApi
3045                 'tw.CountApiReply = SettingDialog.CountApiReply
3046                 tw.TinyUrlResolve = SettingDialog.TinyUrlResolve
3047                 tw.RestrictFavCheck = SettingDialog.RestrictFavCheck
3048                 tw.ReadOwnPost = SettingDialog.ReadOwnPost
3049                 tw.UseSsl = SettingDialog.UseSsl
3050                 ShortUrl.IsResolve = SettingDialog.TinyUrlResolve
3051                 ShortUrl.BitlyId = SettingDialog.BitlyUser
3052                 ShortUrl.BitlyKey = SettingDialog.BitlyPwd
3053                 HttpTwitter.TwitterUrl = _cfgCommon.TwitterUrl
3054                 HttpTwitter.TwitterSearchUrl = _cfgCommon.TwitterSearchUrl
3055
3056                 HttpConnection.InitializeConnection(SettingDialog.DefaultTimeOut, _
3057                                                     SettingDialog.SelectedProxyType, _
3058                                                     SettingDialog.ProxyAddress, _
3059                                                     SettingDialog.ProxyPort, _
3060                                                     SettingDialog.ProxyUser, _
3061                                                     SettingDialog.ProxyPassword)
3062                 Try
3063                     If SettingDialog.TabIconDisp Then
3064                         RemoveHandler ListTab.DrawItem, AddressOf ListTab_DrawItem
3065                         ListTab.DrawMode = TabDrawMode.Normal
3066                         ListTab.ImageList = Me.TabImage
3067                     Else
3068                         RemoveHandler ListTab.DrawItem, AddressOf ListTab_DrawItem
3069                         AddHandler ListTab.DrawItem, AddressOf ListTab_DrawItem
3070                         ListTab.DrawMode = TabDrawMode.OwnerDrawFixed
3071                         ListTab.ImageList = Nothing
3072                     End If
3073                 Catch ex As Exception
3074                     ex.Data("Instance") = "ListTab(TabIconDisp)"
3075                     ex.Data("IsTerminatePermission") = False
3076                     Throw
3077                 End Try
3078
3079                 Try
3080                     If Not SettingDialog.UnreadManage Then
3081                         ReadedStripMenuItem.Enabled = False
3082                         UnreadStripMenuItem.Enabled = False
3083                         If SettingDialog.TabIconDisp Then
3084                             For Each myTab As TabPage In ListTab.TabPages
3085                                 myTab.ImageIndex = -1
3086                             Next
3087                         End If
3088                     Else
3089                         ReadedStripMenuItem.Enabled = True
3090                         UnreadStripMenuItem.Enabled = True
3091                     End If
3092                 Catch ex As Exception
3093                     ex.Data("Instance") = "ListTab(UnreadManage)"
3094                     ex.Data("IsTerminatePermission") = False
3095                     Throw
3096                 End Try
3097
3098                 Try
3099                     For Each mytab As TabPage In ListTab.TabPages
3100                         Dim lst As DetailsListView = DirectCast(mytab.Tag, DetailsListView)
3101                         lst.GridLines = SettingDialog.ShowGrid
3102                     Next
3103                 Catch ex As Exception
3104                     ex.Data("Instance") = "ListTab(ShowGrid)"
3105                     ex.Data("IsTerminatePermission") = False
3106                     Throw
3107                 End Try
3108
3109                 PlaySoundMenuItem.Checked = SettingDialog.PlaySound
3110                 Me.PlaySoundFileMenuItem.Checked = SettingDialog.PlaySound
3111                 _fntUnread = SettingDialog.FontUnread
3112                 _clUnread = SettingDialog.ColorUnread
3113                 _fntReaded = SettingDialog.FontReaded
3114                 _clReaded = SettingDialog.ColorReaded
3115                 _clFav = SettingDialog.ColorFav
3116                 _clOWL = SettingDialog.ColorOWL
3117                 _clRetweet = SettingDialog.ColorRetweet
3118                 _fntDetail = SettingDialog.FontDetail
3119                 _clDetail = SettingDialog.ColorDetail
3120                 _clDetailLink = SettingDialog.ColorDetailLink
3121                 _clDetailBackcolor = SettingDialog.ColorDetailBackcolor
3122                 _clSelf = SettingDialog.ColorSelf
3123                 _clAtSelf = SettingDialog.ColorAtSelf
3124                 _clTarget = SettingDialog.ColorTarget
3125                 _clAtTarget = SettingDialog.ColorAtTarget
3126                 _clAtFromTarget = SettingDialog.ColorAtFromTarget
3127                 _clAtTo = SettingDialog.ColorAtTo
3128                 _clListBackcolor = SettingDialog.ColorListBackcolor
3129                 _clInputBackcolor = SettingDialog.ColorInputBackcolor
3130                 _clInputFont = SettingDialog.ColorInputFont
3131                 _fntInputFont = SettingDialog.FontInputFont
3132                 Try
3133                     If StatusText.Focused Then StatusText.BackColor = _clInputBackcolor
3134                     StatusText.Font = _fntInputFont
3135                     StatusText.ForeColor = _clInputFont
3136                 Catch ex As Exception
3137                     MessageBox.Show(ex.Message)
3138                 End Try
3139
3140                 _brsForeColorUnread.Dispose()
3141                 _brsForeColorReaded.Dispose()
3142                 _brsForeColorFav.Dispose()
3143                 _brsForeColorOWL.Dispose()
3144                 _brsForeColorRetweet.Dispose()
3145                 _brsForeColorUnread = New SolidBrush(_clUnread)
3146                 _brsForeColorReaded = New SolidBrush(_clReaded)
3147                 _brsForeColorFav = New SolidBrush(_clFav)
3148                 _brsForeColorOWL = New SolidBrush(_clOWL)
3149                 _brsForeColorRetweet = New SolidBrush(_clRetweet)
3150                 _brsBackColorMine.Dispose()
3151                 _brsBackColorAt.Dispose()
3152                 _brsBackColorYou.Dispose()
3153                 _brsBackColorAtYou.Dispose()
3154                 _brsBackColorAtFromTarget.Dispose()
3155                 _brsBackColorAtTo.Dispose()
3156                 _brsBackColorNone.Dispose()
3157                 _brsBackColorMine = New SolidBrush(_clSelf)
3158                 _brsBackColorAt = New SolidBrush(_clAtSelf)
3159                 _brsBackColorYou = New SolidBrush(_clTarget)
3160                 _brsBackColorAtYou = New SolidBrush(_clAtTarget)
3161                 _brsBackColorAtFromTarget = New SolidBrush(_clAtFromTarget)
3162                 _brsBackColorAtTo = New SolidBrush(_clAtTo)
3163                 _brsBackColorNone = New SolidBrush(_clListBackcolor)
3164                 Try
3165                     If SettingDialog.IsMonospace Then
3166                         detailHtmlFormatHeader = detailHtmlFormatMono1
3167                         detailHtmlFormatFooter = detailHtmlFormatMono7
3168                     Else
3169                         detailHtmlFormatHeader = detailHtmlFormat1
3170                         detailHtmlFormatFooter = detailHtmlFormat7
3171                     End If
3172                     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
3173                     If SettingDialog.IsMonospace Then
3174                         detailHtmlFormatHeader += detailHtmlFormatMono6
3175                     Else
3176                         detailHtmlFormatHeader += detailHtmlFormat6
3177                     End If
3178                 Catch ex As Exception
3179                     ex.Data("Instance") = "Font"
3180                     ex.Data("IsTerminatePermission") = False
3181                     Throw
3182                 End Try
3183                 Try
3184                     _statuses.SetUnreadManage(SettingDialog.UnreadManage)
3185                 Catch ex As Exception
3186                     ex.Data("Instance") = "_statuses"
3187                     ex.Data("IsTerminatePermission") = False
3188                     Throw
3189                 End Try
3190
3191                 Try
3192                     For Each tb As TabPage In ListTab.TabPages
3193                         If SettingDialog.TabIconDisp Then
3194                             If _statuses.Tabs(tb.Text).UnreadCount = 0 Then
3195                                 tb.ImageIndex = -1
3196                             Else
3197                                 tb.ImageIndex = 0
3198                             End If
3199                         End If
3200                         If tb.Tag IsNot Nothing AndAlso tb.Controls.Count > 0 Then
3201                             DirectCast(tb.Tag, DetailsListView).Font = _fntReaded
3202                             DirectCast(tb.Tag, DetailsListView).BackColor = _clListBackcolor
3203                         End If
3204                     Next
3205                 Catch ex As Exception
3206                     ex.Data("Instance") = "ListTab(TabIconDisp no2)"
3207                     ex.Data("IsTerminatePermission") = False
3208                     Throw
3209                 End Try
3210                 SetMainWindowTitle()
3211                 SetNotifyIconText()
3212
3213                 _itemCache = Nothing
3214                 _postCache = Nothing
3215                 If _curList IsNot Nothing Then _curList.Refresh()
3216                 ListTab.Refresh()
3217
3218                 Outputz.Key = SettingDialog.OutputzKey
3219                 Outputz.Enabled = SettingDialog.OutputzEnabled
3220                 Select Case SettingDialog.OutputzUrlmode
3221                     Case OutputzUrlmode.twittercom
3222                         Outputz.OutUrl = "http://twitter.com/"
3223                     Case OutputzUrlmode.twittercomWithUsername
3224                         Outputz.OutUrl = "http://twitter.com/" + tw.Username
3225                 End Select
3226
3227                 _hookGlobalHotkey.UnregisterAllOriginalHotkey()
3228                 If SettingDialog.HotkeyEnabled Then
3229                     '''グローバルホットキーの登録。設定で変更可能にするかも
3230                     Dim modKey As HookGlobalHotkey.ModKeys = HookGlobalHotkey.ModKeys.None
3231                     If (SettingDialog.HotkeyMod And Keys.Alt) = Keys.Alt Then modKey = modKey Or HookGlobalHotkey.ModKeys.Alt
3232                     If (SettingDialog.HotkeyMod And Keys.Control) = Keys.Control Then modKey = modKey Or HookGlobalHotkey.ModKeys.Ctrl
3233                     If (SettingDialog.HotkeyMod And Keys.Shift) = Keys.Shift Then modKey = modKey Or HookGlobalHotkey.ModKeys.Shift
3234                     If (SettingDialog.HotkeyMod And Keys.LWin) = Keys.LWin Then modKey = modKey Or HookGlobalHotkey.ModKeys.Win
3235
3236                     _hookGlobalHotkey.RegisterOriginalHotkey(SettingDialog.HotkeyKey, SettingDialog.HotkeyValue, modKey)
3237                 End If
3238
3239                 If uid <> tw.Username Then Me.doGetFollowersMenu()
3240
3241                 SetImageServiceCombo()
3242
3243                 Try
3244                     StatusText_TextChanged(Nothing, Nothing)
3245                 Catch ex As Exception
3246
3247                 End Try
3248             End SyncLock
3249         End If
3250
3251         Twitter.AccountState = ACCOUNT_STATE.Valid
3252
3253         Me.TopMost = SettingDialog.AlwaysTop
3254         SaveConfigsAll(False)
3255     End Sub
3256
3257     Private Sub PostBrowser_Navigated(ByVal sender As Object, ByVal e As System.Windows.Forms.WebBrowserNavigatedEventArgs) Handles PostBrowser.Navigated
3258         If e.Url.AbsoluteUri <> "about:blank" Then
3259             DispSelectedPost()
3260             OpenUriAsync(e.Url.OriginalString)
3261         End If
3262     End Sub
3263
3264     Private Sub PostBrowser_Navigating(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserNavigatingEventArgs) Handles PostBrowser.Navigating
3265         If e.Url.Scheme = "data" Then
3266             StatusLabelUrl.Text = PostBrowser.StatusText.Replace("&", "&&")
3267         ElseIf e.Url.AbsoluteUri <> "about:blank" Then
3268             e.Cancel = True
3269
3270             If e.Url.AbsoluteUri.StartsWith("http://twitter.com/search?q=%23") OrElse _
3271                e.Url.AbsoluteUri.StartsWith("https://twitter.com/search?q=%23") Then
3272                 'ハッシュタグの場合は、タブで開く
3273                 Dim urlStr As String = HttpUtility.UrlDecode(e.Url.AbsoluteUri)
3274                 Dim hash As String = urlStr.Substring(urlStr.IndexOf("#"))
3275                 HashSupl.AddItem(hash)
3276                 HashMgr.AddHashToHistory(hash.Trim, False)
3277                 AddNewTabForSearch(hash)
3278                 Exit Sub
3279             Else
3280                 Dim m As Match = Regex.Match(e.Url.AbsoluteUri, "^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)$")
3281                 If m.Success AndAlso IsTwitterId(m.Result("${ScreenName}")) Then
3282                     ' Ctrlを押しながらリンクをクリックした場合は設定と逆の動作をする
3283                     If SettingDialog.OpenUserTimeline Then
3284                         If My.Computer.Keyboard.CtrlKeyDown Then
3285                             OpenUriAsync(e.Url.OriginalString)
3286                         Else
3287                             Me.AddNewTabForUserTimeline(m.Result("${ScreenName}"))
3288                         End If
3289                     Else
3290                         If My.Computer.Keyboard.CtrlKeyDown Then
3291                             Me.AddNewTabForUserTimeline(m.Result("${ScreenName}"))
3292                         Else
3293                             OpenUriAsync(e.Url.OriginalString)
3294                         End If
3295                     End If
3296                 Else
3297                     OpenUriAsync(e.Url.OriginalString)
3298                 End If
3299             End If
3300         End If
3301     End Sub
3302
3303     Public Sub AddNewTabForSearch(ByVal searchWord As String)
3304         '同一検索条件のタブが既に存在すれば、そのタブアクティブにして終了
3305         For Each tb As TabClass In _statuses.GetTabsByType(TabUsageType.PublicSearch)
3306             If tb.SearchWords = searchWord AndAlso tb.SearchLang = "" Then
3307                 For Each tp As TabPage In ListTab.TabPages
3308                     If tb.TabName = tp.Text Then
3309                         ListTab.SelectedTab = tp
3310                         Exit Sub
3311                     End If
3312                 Next
3313             End If
3314         Next
3315         'ユニークなタブ名生成
3316         Dim tabName As String = searchWord
3317         For i As Integer = 0 To 100
3318             If _statuses.ContainsTab(tabName) Then
3319                 tabName += "_"
3320             Else
3321                 Exit For
3322             End If
3323         Next
3324         'タブ追加
3325         AddNewTab(tabName, False, TabUsageType.PublicSearch)
3326         _statuses.AddTab(tabName, TabUsageType.PublicSearch, Nothing)
3327         '追加したタブをアクティブに
3328         ListTab.SelectedIndex = ListTab.TabPages.Count - 1
3329         '検索条件の設定
3330         Dim cmb As ComboBox = DirectCast(ListTab.SelectedTab.Controls("panelSearch").Controls("comboSearch"), ComboBox)
3331         cmb.Items.Add(searchWord)
3332         cmb.Text = searchWord
3333         SaveConfigsTabs()
3334         '検索実行
3335         Me.SearchButton_Click(ListTab.SelectedTab.Controls("panelSearch").Controls("comboSearch"), Nothing)
3336     End Sub
3337
3338     Private Sub ShowUserTimeline()
3339         If Not Me.ExistCurrentPost Then Exit Sub
3340         AddNewTabForUserTimeline(_curPost.ScreenName)
3341     End Sub
3342
3343     Public Sub AddNewTabForUserTimeline(ByVal user As String)
3344         '同一検索条件のタブが既に存在すれば、そのタブアクティブにして終了
3345         For Each tb As TabClass In _statuses.GetTabsByType(TabUsageType.UserTimeline)
3346             If tb.User = user Then
3347                 For Each tp As TabPage In ListTab.TabPages
3348                     If tb.TabName = tp.Text Then
3349                         ListTab.SelectedTab = tp
3350                         Exit Sub
3351                     End If
3352                 Next
3353             End If
3354         Next
3355         'ユニークなタブ名生成
3356         Dim tabName As String = "user:" + user
3357         While _statuses.ContainsTab(tabName)
3358             tabName += "_"
3359         End While
3360         'タブ追加
3361         _statuses.AddTab(tabName, TabUsageType.UserTimeline, Nothing)
3362         _statuses.Tabs(tabName).User = user
3363         AddNewTab(tabName, False, TabUsageType.UserTimeline)
3364         '追加したタブをアクティブに
3365         ListTab.SelectedIndex = ListTab.TabPages.Count - 1
3366         SaveConfigsTabs()
3367         '検索実行
3368
3369         GetTimeline(WORKERTYPE.UserTimeline, 1, 0, tabName)
3370     End Sub
3371
3372     Public Function AddNewTab(ByVal tabName As String, ByVal startup As Boolean, ByVal tabType As TabUsageType, Optional ByVal listInfo As ListElement = Nothing) As Boolean
3373         '重複チェック
3374         For Each tb As TabPage In ListTab.TabPages
3375             If tb.Text = tabName Then Return False
3376         Next
3377
3378         '新規タブ名チェック
3379         If tabName = My.Resources.AddNewTabText1 Then Return False
3380
3381         'タブタイプ重複チェック
3382         If Not startup Then
3383             If tabType = TabUsageType.DirectMessage OrElse _
3384                tabType = TabUsageType.Favorites OrElse _
3385                tabType = TabUsageType.Home OrElse _
3386                tabType = TabUsageType.Mentions OrElse _
3387                tabType = TabUsageType.Related Then
3388                 If _statuses.GetTabByType(tabType) IsNot Nothing Then Return False
3389             End If
3390         End If
3391
3392         Dim _tabPage As TabPage = New TabPage
3393         Dim _listCustom As DetailsListView = New DetailsListView
3394         Dim _colHd1 As ColumnHeader = New ColumnHeader()  'アイコン
3395         Dim _colHd2 As ColumnHeader = New ColumnHeader()   'ニックネーム
3396         Dim _colHd3 As ColumnHeader = New ColumnHeader()   '本文
3397         Dim _colHd4 As ColumnHeader = New ColumnHeader()   '日付
3398         Dim _colHd5 As ColumnHeader = New ColumnHeader()   'ユーザID
3399         Dim _colHd6 As ColumnHeader = New ColumnHeader()   '未読
3400         Dim _colHd7 As ColumnHeader = New ColumnHeader()   'マーク&プロテクト
3401         Dim _colHd8 As ColumnHeader = New ColumnHeader()   'ソース
3402
3403         Dim cnt As Integer = ListTab.TabPages.Count
3404
3405         '''ToDo:Create and set controls follow tabtypes
3406
3407         Me.SplitContainer1.Panel1.SuspendLayout()
3408         Me.SplitContainer1.Panel2.SuspendLayout()
3409         Me.SplitContainer1.SuspendLayout()
3410         Me.ListTab.SuspendLayout()
3411         Me.SuspendLayout()
3412
3413         _tabPage.SuspendLayout()
3414
3415         ''' UserTimeline関連
3416         Dim label As Label = Nothing
3417         If tabType = TabUsageType.UserTimeline OrElse tabType = TabUsageType.Lists Then
3418             label = New Label()
3419             label.Dock = DockStyle.Top
3420             label.Name = "labelUser"
3421             If tabType = TabUsageType.Lists Then
3422                 label.Text = listInfo.ToString()
3423             Else
3424                 label.Text = _statuses.Tabs(tabName).User + "'s Timeline"
3425             End If
3426             label.TextAlign = ContentAlignment.MiddleLeft
3427             Using tmpComboBox As New ComboBox()
3428                 label.Height = tmpComboBox.Height
3429             End Using
3430             _tabPage.Controls.Add(label)
3431         End If
3432
3433         ''' 検索関連の準備
3434         Dim pnl As Panel = Nothing
3435         If tabType = TabUsageType.PublicSearch Then
3436             pnl = New Panel
3437
3438             Dim lbl As New Label
3439             Dim cmb As New ComboBox
3440             Dim btn As New Button
3441             Dim cmbLang As New ComboBox
3442
3443             pnl.SuspendLayout()
3444
3445             pnl.Controls.Add(cmb)
3446             pnl.Controls.Add(cmbLang)
3447             pnl.Controls.Add(btn)
3448             pnl.Controls.Add(lbl)
3449             pnl.Name = "panelSearch"
3450             pnl.Dock = DockStyle.Top
3451             pnl.Height = cmb.Height
3452             AddHandler pnl.Enter, AddressOf SearchControls_Enter
3453             AddHandler pnl.Leave, AddressOf SearchControls_Leave
3454
3455             cmb.Text = ""
3456             cmb.Anchor = AnchorStyles.Left Or AnchorStyles.Right
3457             cmb.Dock = DockStyle.Fill
3458             cmb.Name = "comboSearch"
3459             cmb.DropDownStyle = ComboBoxStyle.DropDown
3460             cmb.ImeMode = Windows.Forms.ImeMode.NoControl
3461             cmb.TabStop = False
3462             cmb.AutoCompleteMode = AutoCompleteMode.None
3463
3464             If _statuses.ContainsTab(tabName) Then
3465                 cmb.Items.Add(_statuses.Tabs(tabName).SearchWords)
3466                 cmb.Text = _statuses.Tabs(tabName).SearchWords
3467             End If
3468
3469             cmbLang.Text = ""
3470             cmbLang.Anchor = AnchorStyles.Left Or AnchorStyles.Right
3471             cmbLang.Dock = DockStyle.Right
3472             cmbLang.Width = 50
3473             cmbLang.Name = "comboLang"
3474             cmbLang.DropDownStyle = ComboBoxStyle.DropDownList
3475             cmbLang.TabStop = False
3476             cmbLang.Items.Add("")
3477             cmbLang.Items.Add("ja")
3478             cmbLang.Items.Add("en")
3479             cmbLang.Items.Add("ar")
3480             cmbLang.Items.Add("da")
3481             cmbLang.Items.Add("nl")
3482             cmbLang.Items.Add("fa")
3483             cmbLang.Items.Add("fi")
3484             cmbLang.Items.Add("fr")
3485             cmbLang.Items.Add("de")
3486             cmbLang.Items.Add("hu")
3487             cmbLang.Items.Add("is")
3488             cmbLang.Items.Add("it")
3489             cmbLang.Items.Add("no")
3490             cmbLang.Items.Add("pl")
3491             cmbLang.Items.Add("pt")
3492             cmbLang.Items.Add("ru")
3493             cmbLang.Items.Add("es")
3494             cmbLang.Items.Add("sv")
3495             cmbLang.Items.Add("th")
3496             If _statuses.ContainsTab(tabName) Then cmbLang.Text = _statuses.Tabs(tabName).SearchLang
3497
3498             lbl.Text = "Search(C-S-f)"
3499             lbl.Name = "label1"
3500             lbl.Dock = DockStyle.Left
3501             lbl.Width = 90
3502             lbl.Height = cmb.Height
3503             lbl.TextAlign = ContentAlignment.MiddleLeft
3504
3505             btn.Text = "Search"
3506             btn.Name = "buttonSearch"
3507             btn.UseVisualStyleBackColor = True
3508             btn.Dock = DockStyle.Right
3509             btn.TabStop = False
3510             AddHandler btn.Click, AddressOf SearchButton_Click
3511         End If
3512
3513         Me.ListTab.Controls.Add(_tabPage)
3514         _tabPage.Controls.Add(_listCustom)
3515
3516         If tabType = TabUsageType.PublicSearch Then _tabPage.Controls.Add(pnl)
3517         If tabType = TabUsageType.UserTimeline OrElse tabType = TabUsageType.Lists Then _tabPage.Controls.Add(label)
3518
3519         _tabPage.Location = New Point(4, 4)
3520         _tabPage.Name = "CTab" + cnt.ToString()
3521         _tabPage.Size = New Size(380, 260)
3522         _tabPage.TabIndex = 2 + cnt
3523         _tabPage.Text = tabName
3524         _tabPage.UseVisualStyleBackColor = True
3525
3526         _listCustom.AllowColumnReorder = True
3527         If Not _iconCol Then
3528             _listCustom.Columns.AddRange(New ColumnHeader() {_colHd1, _colHd2, _colHd3, _colHd4, _colHd5, _colHd6, _colHd7, _colHd8})
3529         Else
3530             _listCustom.Columns.AddRange(New ColumnHeader() {_colHd1, _colHd3})
3531         End If
3532         _listCustom.ContextMenuStrip = Me.ContextMenuOperate
3533         _listCustom.Dock = DockStyle.Fill
3534         _listCustom.FullRowSelect = True
3535         _listCustom.HideSelection = False
3536         _listCustom.Location = New Point(0, 0)
3537         _listCustom.Margin = New Padding(0)
3538         _listCustom.Name = "CList" + Environment.TickCount.ToString()
3539         _listCustom.ShowItemToolTips = True
3540         _listCustom.Size = New Size(380, 260)
3541         _listCustom.UseCompatibleStateImageBehavior = False
3542         _listCustom.View = View.Details
3543         _listCustom.OwnerDraw = True
3544         _listCustom.VirtualMode = True
3545         _listCustom.Font = _fntReaded
3546         _listCustom.BackColor = _clListBackcolor
3547
3548         _listCustom.GridLines = SettingDialog.ShowGrid
3549         _listCustom.AllowDrop = True
3550
3551         AddHandler _listCustom.SelectedIndexChanged, AddressOf MyList_SelectedIndexChanged
3552         AddHandler _listCustom.MouseDoubleClick, AddressOf MyList_MouseDoubleClick
3553         AddHandler _listCustom.ColumnClick, AddressOf MyList_ColumnClick
3554         AddHandler _listCustom.DrawColumnHeader, AddressOf MyList_DrawColumnHeader
3555         AddHandler _listCustom.DragDrop, AddressOf TweenMain_DragDrop
3556         AddHandler _listCustom.DragOver, AddressOf TweenMain_DragOver
3557         AddHandler _listCustom.DrawItem, AddressOf MyList_DrawItem
3558         AddHandler _listCustom.MouseClick, AddressOf MyList_MouseClick
3559         AddHandler _listCustom.ColumnReordered, AddressOf MyList_ColumnReordered
3560         AddHandler _listCustom.ColumnWidthChanged, AddressOf MyList_ColumnWidthChanged
3561         AddHandler _listCustom.CacheVirtualItems, AddressOf MyList_CacheVirtualItems
3562         AddHandler _listCustom.RetrieveVirtualItem, AddressOf MyList_RetrieveVirtualItem
3563         AddHandler _listCustom.DrawSubItem, AddressOf MyList_DrawSubItem
3564         AddHandler _listCustom.HScrolled, AddressOf MyList_HScrolled
3565
3566         InitColumnText()
3567         _colHd1.Text = ColumnText(0)
3568         _colHd1.Width = 48
3569         _colHd2.Text = ColumnText(1)
3570         _colHd2.Width = 80
3571         _colHd3.Text = ColumnText(2)
3572         _colHd3.Width = 300
3573         _colHd4.Text = ColumnText(3)
3574         _colHd4.Width = 50
3575         _colHd5.Text = ColumnText(4)
3576         _colHd5.Width = 50
3577         _colHd6.Text = ColumnText(5)
3578         _colHd6.Width = 16
3579         _colHd7.Text = ColumnText(6)
3580         _colHd7.Width = 16
3581         _colHd8.Text = ColumnText(7)
3582         _colHd8.Width = 50
3583
3584         If _statuses.IsDistributableTab(tabName) Then TabDialog.AddTab(tabName)
3585
3586         _listCustom.SmallImageList = New ImageList()
3587         If _iconSz > 0 Then
3588             _listCustom.SmallImageList.ImageSize = New Size(_iconSz, _iconSz)
3589         End If
3590
3591         Dim dispOrder(7) As Integer
3592         If Not startup Then
3593             For i As Integer = 0 To _curList.Columns.Count - 1
3594                 For j As Integer = 0 To _curList.Columns.Count - 1
3595                     If _curList.Columns(j).DisplayIndex = i Then
3596                         dispOrder(i) = j
3597                         Exit For
3598                     End If
3599                 Next
3600             Next
3601             For i As Integer = 0 To _curList.Columns.Count - 1
3602                 _listCustom.Columns(i).Width = _curList.Columns(i).Width
3603                 _listCustom.Columns(dispOrder(i)).DisplayIndex = i
3604             Next
3605         Else
3606             If _iconCol Then
3607                 _listCustom.Columns(0).Width = _cfgLocal.Width1
3608                 _listCustom.Columns(1).Width = _cfgLocal.Width3
3609                 _listCustom.Columns(0).DisplayIndex = 0
3610                 _listCustom.Columns(1).DisplayIndex = 1
3611             Else
3612                 For i As Integer = 0 To 7
3613                     If _cfgLocal.DisplayIndex1 = i Then
3614                         dispOrder(i) = 0
3615                     ElseIf _cfgLocal.DisplayIndex2 = i Then
3616                         dispOrder(i) = 1
3617                     ElseIf _cfgLocal.DisplayIndex3 = i Then
3618                         dispOrder(i) = 2
3619                     ElseIf _cfgLocal.DisplayIndex4 = i Then
3620                         dispOrder(i) = 3
3621                     ElseIf _cfgLocal.DisplayIndex5 = i Then
3622                         dispOrder(i) = 4
3623                     ElseIf _cfgLocal.DisplayIndex6 = i Then
3624                         dispOrder(i) = 5
3625                     ElseIf _cfgLocal.DisplayIndex7 = i Then
3626                         dispOrder(i) = 6
3627                     ElseIf _cfgLocal.DisplayIndex8 = i Then
3628                         dispOrder(i) = 7
3629                     End If
3630                 Next
3631                 _listCustom.Columns(0).Width = _cfgLocal.Width1
3632                 _listCustom.Columns(1).Width = _cfgLocal.Width2
3633                 _listCustom.Columns(2).Width = _cfgLocal.Width3
3634                 _listCustom.Columns(3).Width = _cfgLocal.Width4
3635                 _listCustom.Columns(4).Width = _cfgLocal.Width5
3636                 _listCustom.Columns(5).Width = _cfgLocal.Width6
3637                 _listCustom.Columns(6).Width = _cfgLocal.Width7
3638                 _listCustom.Columns(7).Width = _cfgLocal.Width8
3639                 For i As Integer = 0 To 7
3640                     _listCustom.Columns(dispOrder(i)).DisplayIndex = i
3641                 Next
3642             End If
3643         End If
3644
3645         If tabType = TabUsageType.PublicSearch Then pnl.ResumeLayout(False)
3646
3647         _tabPage.ResumeLayout(False)
3648
3649         Me.SplitContainer1.Panel1.ResumeLayout(False)
3650         Me.SplitContainer1.Panel2.ResumeLayout(False)
3651         Me.SplitContainer1.ResumeLayout(False)
3652         Me.ListTab.ResumeLayout(False)
3653         Me.ResumeLayout(False)
3654         Me.PerformLayout()
3655         _tabPage.Tag = _listCustom
3656         Return True
3657     End Function
3658
3659     Public Function RemoveSpecifiedTab(ByVal TabName As String, ByVal confirm As Boolean) As Boolean
3660         Dim idx As Integer = 0
3661         For idx = 0 To ListTab.TabPages.Count - 1
3662             If ListTab.TabPages(idx).Text = TabName Then Exit For
3663         Next
3664
3665         If _statuses.IsDefaultTab(TabName) Then Return False
3666
3667         If confirm Then
3668             Dim tmp As String = String.Format(My.Resources.RemoveSpecifiedTabText1, Environment.NewLine)
3669             If MessageBox.Show(tmp, TabName + " " + My.Resources.RemoveSpecifiedTabText2, _
3670                              MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.Cancel Then
3671                 Return False
3672             End If
3673         End If
3674
3675         SetListProperty()   '他のタブに列幅等を反映
3676
3677         Dim tabType As TabUsageType = _statuses.Tabs(TabName).TabType
3678
3679         'オブジェクトインスタンスの削除
3680         Me.SplitContainer1.Panel1.SuspendLayout()
3681         Me.SplitContainer1.Panel2.SuspendLayout()
3682         Me.SplitContainer1.SuspendLayout()
3683         Me.ListTab.SuspendLayout()
3684         Me.SuspendLayout()
3685
3686         Dim _tabPage As TabPage = ListTab.TabPages(idx)
3687         Dim _listCustom As DetailsListView = DirectCast(_tabPage.Tag, DetailsListView)
3688         _tabPage.Tag = Nothing
3689
3690         _tabPage.SuspendLayout()
3691
3692         If Me.ListTab.SelectedTab Is Me.ListTab.TabPages(idx) Then
3693             Me.ListTab.SelectTab(If(Me._beforeSelectedTab IsNot Nothing AndAlso Me.ListTab.TabPages.Contains(Me._beforeSelectedTab), Me._beforeSelectedTab, Me.ListTab.TabPages(0)))
3694         End If
3695         Me.ListTab.Controls.Remove(_tabPage)
3696
3697         Dim pnl As Control = Nothing
3698         If tabType = TabUsageType.PublicSearch Then
3699             pnl = _tabPage.Controls("panelSearch")
3700             For Each ctrl As Control In pnl.Controls
3701                 If ctrl.Name = "buttonSearch" Then
3702                     RemoveHandler ctrl.Click, AddressOf SearchButton_Click
3703                 End If
3704                 RemoveHandler ctrl.Enter, AddressOf SearchControls_Enter
3705                 RemoveHandler ctrl.Leave, AddressOf SearchControls_Leave
3706                 pnl.Controls.Remove(ctrl)
3707                 ctrl.Dispose()
3708             Next
3709             _tabPage.Controls.Remove(pnl)
3710         End If
3711
3712         _tabPage.Controls.Remove(_listCustom)
3713         _listCustom.Columns.Clear()
3714         _listCustom.ContextMenuStrip = Nothing
3715
3716         RemoveHandler _listCustom.SelectedIndexChanged, AddressOf MyList_SelectedIndexChanged
3717         RemoveHandler _listCustom.MouseDoubleClick, AddressOf MyList_MouseDoubleClick
3718         RemoveHandler _listCustom.ColumnClick, AddressOf MyList_ColumnClick
3719         RemoveHandler _listCustom.DrawColumnHeader, AddressOf MyList_DrawColumnHeader
3720         RemoveHandler _listCustom.DragDrop, AddressOf TweenMain_DragDrop
3721         RemoveHandler _listCustom.DragOver, AddressOf TweenMain_DragOver
3722         RemoveHandler _listCustom.DrawItem, AddressOf MyList_DrawItem
3723         RemoveHandler _listCustom.MouseClick, AddressOf MyList_MouseClick
3724         RemoveHandler _listCustom.ColumnReordered, AddressOf MyList_ColumnReordered
3725         RemoveHandler _listCustom.ColumnWidthChanged, AddressOf MyList_ColumnWidthChanged
3726         RemoveHandler _listCustom.CacheVirtualItems, AddressOf MyList_CacheVirtualItems
3727         RemoveHandler _listCustom.RetrieveVirtualItem, AddressOf MyList_RetrieveVirtualItem
3728         RemoveHandler _listCustom.DrawSubItem, AddressOf MyList_DrawSubItem
3729         RemoveHandler _listCustom.HScrolled, AddressOf MyList_HScrolled
3730
3731         TabDialog.RemoveTab(TabName)
3732
3733         _listCustom.SmallImageList = Nothing
3734         _listCustom.ListViewItemSorter = Nothing
3735
3736         'キャッシュのクリア
3737         If _curTab.Equals(_tabPage) Then
3738             _curTab = Nothing
3739             _curItemIndex = -1
3740             _curList = Nothing
3741             _curPost = Nothing
3742         End If
3743         _itemCache = Nothing
3744         _itemCacheIndex = -1
3745         _postCache = Nothing
3746
3747         _tabPage.ResumeLayout(False)
3748
3749         Me.SplitContainer1.Panel1.ResumeLayout(False)
3750         Me.SplitContainer1.Panel2.ResumeLayout(False)
3751         Me.SplitContainer1.ResumeLayout(False)
3752         Me.ListTab.ResumeLayout(False)
3753         Me.ResumeLayout(False)
3754         Me.PerformLayout()
3755
3756         _tabPage.Dispose()
3757         _listCustom.Dispose()
3758         _statuses.RemoveTab(TabName)
3759
3760         For Each tp As TabPage In ListTab.TabPages
3761             Dim lst As DetailsListView = DirectCast(tp.Tag, DetailsListView)
3762             If lst.VirtualListSize <> _statuses.Tabs(tp.Text).AllCount Then
3763                 lst.VirtualListSize = _statuses.Tabs(tp.Text).AllCount
3764             End If
3765         Next
3766
3767         Return True
3768     End Function
3769
3770     Private Sub ListTab_Deselected(ByVal sender As Object, ByVal e As System.Windows.Forms.TabControlEventArgs) Handles ListTab.Deselected
3771         _itemCache = Nothing
3772         _itemCacheIndex = -1
3773         _postCache = Nothing
3774         _beforeSelectedTab = e.TabPage
3775     End Sub
3776
3777     Private Sub ListTab_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseMove
3778         'タブのD&D
3779         Dim cpos As New Point(e.X, e.Y)
3780
3781         If e.Button = Windows.Forms.MouseButtons.Left AndAlso _tabDrag Then
3782             Dim tn As String = ""
3783             Dim dragEnableRectangle As New Rectangle(CInt(_tabMouseDownPoint.X - (SystemInformation.DragSize.Width / 2)), CInt(_tabMouseDownPoint.Y - (SystemInformation.DragSize.Height / 2)), SystemInformation.DragSize.Width, SystemInformation.DragSize.Height)
3784             If Not dragEnableRectangle.Contains(e.Location) Then
3785                 'タブが多段の場合にはMouseDownの前の段階で選択されたタブの段が変わっているので、このタイミングでカーソルの位置からタブを判定出来ない。
3786                 tn = ListTab.SelectedTab.Text
3787             End If
3788
3789             If tn = "" Then Exit Sub
3790
3791             For Each tb As TabPage In ListTab.TabPages
3792                 If tb.Text = tn Then
3793                     ListTab.DoDragDrop(tb, DragDropEffects.All)
3794                     Exit For
3795                 End If
3796             Next
3797         Else
3798             _tabDrag = False
3799         End If
3800
3801         For i As Integer = 0 To ListTab.TabPages.Count - 1
3802             Dim rect As Rectangle = ListTab.GetTabRect(i)
3803             If rect.Left <= cpos.X And cpos.X <= rect.Right And _
3804                rect.Top <= cpos.Y And cpos.Y <= rect.Bottom Then
3805                 _rclickTabName = ListTab.TabPages(i).Text
3806                 Exit For
3807             End If
3808         Next
3809     End Sub
3810
3811     Private Sub ListTab_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListTab.SelectedIndexChanged
3812         '_curList.Refresh()
3813         DispSelectedPost()
3814         SetMainWindowTitle()
3815         SetStatusLabelUrl()
3816         If ListTab.Focused OrElse DirectCast(ListTab.SelectedTab.Tag, Control).Focused Then Me.Tag = ListTab.Tag
3817         TabMenuControl(ListTab.SelectedTab.Text)
3818     End Sub
3819
3820     Private Sub SetListProperty()
3821         '削除などで見つからない場合は処理せず
3822         If _curList Is Nothing Then Exit Sub
3823         If Not _isColumnChanged Then Exit Sub
3824
3825         Dim dispOrder(_curList.Columns.Count - 1) As Integer
3826         For i As Integer = 0 To _curList.Columns.Count - 1
3827             For j As Integer = 0 To _curList.Columns.Count - 1
3828                 If _curList.Columns(j).DisplayIndex = i Then
3829                     dispOrder(i) = j
3830                     Exit For
3831                 End If
3832             Next
3833         Next
3834
3835         '列幅、列並びを他のタブに設定
3836         For Each tb As TabPage In ListTab.TabPages
3837             If Not tb.Equals(_curTab) Then
3838                 If tb.Tag IsNot Nothing AndAlso tb.Controls.Count > 0 Then
3839                     Dim lst As DetailsListView = DirectCast(tb.Tag, DetailsListView)
3840                     For i As Integer = 0 To lst.Columns.Count - 1
3841                         lst.Columns(dispOrder(i)).DisplayIndex = i
3842                         lst.Columns(i).Width = _curList.Columns(i).Width
3843                     Next
3844                 End If
3845             End If
3846         Next
3847
3848         _isColumnChanged = False
3849     End Sub
3850
3851     Private Sub PostBrowser_StatusTextChanged(ByVal sender As Object, ByVal e As EventArgs) Handles PostBrowser.StatusTextChanged
3852         If PostBrowser.StatusText.StartsWith("http") OrElse PostBrowser.StatusText.StartsWith("ftp") _
3853                 OrElse PostBrowser.StatusText.StartsWith("data") Then
3854             StatusLabelUrl.Text = PostBrowser.StatusText.Replace("&", "&&")
3855         End If
3856         If PostBrowser.StatusText = "" Then
3857             SetStatusLabelUrl()
3858         End If
3859     End Sub
3860
3861     Private Sub StatusText_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles StatusText.KeyPress
3862         If e.KeyChar = "@" Then
3863             If Not SettingDialog.UseAtIdSupplement Then Exit Sub
3864             '@マーク
3865             ShowSuplDialog(StatusText, AtIdSupl)
3866             e.Handled = True
3867         ElseIf e.KeyChar = "#" Then
3868             If Not SettingDialog.UseHashSupplement Then Exit Sub
3869             ShowSuplDialog(StatusText, HashSupl)
3870             e.Handled = True
3871         End If
3872     End Sub
3873
3874     Public Overloads Sub ShowSuplDialog(ByVal owner As TextBox, ByVal dialog As AtIdSupplement)
3875         ShowSuplDialog(owner, dialog, 0, "")
3876     End Sub
3877
3878     Public Overloads Sub ShowSuplDialog(ByVal owner As TextBox, ByVal dialog As AtIdSupplement, ByVal offset As Integer)
3879         ShowSuplDialog(owner, dialog, offset, "")
3880     End Sub
3881
3882     Public Overloads Sub ShowSuplDialog(ByVal owner As TextBox, ByVal dialog As AtIdSupplement, ByVal offset As Integer, ByVal startswith As String)
3883         dialog.StartsWith = startswith
3884         If dialog.Visible Then
3885             dialog.Focus()
3886         Else
3887             dialog.ShowDialog()
3888         End If
3889         Me.TopMost = SettingDialog.AlwaysTop
3890         Dim selStart As Integer = owner.SelectionStart
3891         Dim fHalf As String = ""
3892         Dim eHalf As String = ""
3893         If dialog.DialogResult = Windows.Forms.DialogResult.OK Then
3894             If dialog.inputText <> "" Then
3895                 If selStart > 0 Then
3896                     fHalf = owner.Text.Substring(0, selStart - offset)
3897                 End If
3898                 If selStart < owner.Text.Length Then
3899                     eHalf = owner.Text.Substring(selStart)
3900                 End If
3901                 owner.Text = fHalf + dialog.inputText + eHalf
3902                 owner.SelectionStart = selStart + dialog.inputText.Length
3903             End If
3904         Else
3905             If selStart > 0 Then
3906                 fHalf = owner.Text.Substring(0, selStart)
3907             End If
3908             If selStart < owner.Text.Length Then
3909                 eHalf = owner.Text.Substring(selStart)
3910             End If
3911             owner.Text = fHalf + eHalf
3912             If selStart > 0 Then
3913                 owner.SelectionStart = selStart
3914             End If
3915         End If
3916         owner.Focus()
3917     End Sub
3918
3919     Private Sub StatusText_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles StatusText.KeyUp
3920         'スペースキーで未読ジャンプ
3921         If Not e.Alt AndAlso Not e.Control AndAlso Not e.Shift Then
3922             If e.KeyCode = Keys.Space OrElse e.KeyCode = Keys.ProcessKey Then
3923                 Dim isSpace As Boolean = False
3924                 For Each c As Char In StatusText.Text.ToCharArray
3925                     If c = " " OrElse c = " " Then
3926                         isSpace = True
3927                     Else
3928                         isSpace = False
3929                         Exit For
3930                     End If
3931                 Next
3932                 If isSpace Then
3933                     e.Handled = True
3934                     StatusText.Text = ""
3935                     JumpUnreadMenuItem_Click(Nothing, Nothing)
3936                 End If
3937             End If
3938         End If
3939         Me.StatusText_TextChanged(Nothing, Nothing)
3940     End Sub
3941
3942     Private Sub StatusText_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusText.TextChanged
3943         '文字数カウント
3944         Dim pLen As Integer = GetRestStatusCount(True, False)
3945         lblLen.Text = pLen.ToString()
3946         If pLen < 0 Then
3947             StatusText.ForeColor = Color.Red
3948         Else
3949             StatusText.ForeColor = _clInputFont
3950         End If
3951         If StatusText.Text = "" Then
3952             _reply_to_id = 0
3953             _reply_to_name = ""
3954         End If
3955     End Sub
3956
3957     Private Function GetRestStatusCount(ByVal isAuto As Boolean, ByVal isAddFooter As Boolean) As Integer
3958         '文字数カウント
3959         Dim pLen As Integer = 140 - StatusText.Text.Length
3960         If (isAuto AndAlso Not My.Computer.Keyboard.CtrlKeyDown AndAlso SettingDialog.PostShiftEnter) OrElse _
3961            (isAuto AndAlso Not My.Computer.Keyboard.ShiftKeyDown AndAlso Not SettingDialog.PostShiftEnter) OrElse _
3962            (Not isAuto AndAlso isAddFooter) Then
3963             If SettingDialog.UseRecommendStatus Then
3964                 pLen -= SettingDialog.RecommendStatusText.Length
3965             ElseIf SettingDialog.Status.Length > 0 Then
3966                 pLen -= SettingDialog.Status.Length + 1
3967             End If
3968         End If
3969         If HashMgr.UseHash <> "" Then
3970             pLen -= HashMgr.UseHash.Length + 1
3971         End If
3972         Return pLen
3973     End Function
3974
3975     Private Sub MyList_CacheVirtualItems(ByVal sender As System.Object, ByVal e As System.Windows.Forms.CacheVirtualItemsEventArgs)
3976         If _itemCache IsNot Nothing AndAlso _
3977            e.StartIndex >= _itemCacheIndex AndAlso _
3978            e.EndIndex < _itemCacheIndex + _itemCache.Length AndAlso _
3979            _curList.Equals(sender) Then
3980             'If the newly requested cache is a subset of the old cache, 
3981             'no need to rebuild everything, so do nothing.
3982             Return
3983         End If
3984
3985         'Now we need to rebuild the cache.
3986         If _curList.Equals(sender) Then CreateCache(e.StartIndex, e.EndIndex)
3987     End Sub
3988
3989     Private Sub MyList_RetrieveVirtualItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.RetrieveVirtualItemEventArgs)
3990         If _itemCache IsNot Nothing AndAlso e.ItemIndex >= _itemCacheIndex AndAlso e.ItemIndex < _itemCacheIndex + _itemCache.Length AndAlso _curList.Equals(sender) Then
3991             'A cache hit, so get the ListViewItem from the cache instead of making a new one.
3992             e.Item = _itemCache(e.ItemIndex - _itemCacheIndex)
3993         Else
3994             'A cache miss, so create a new ListViewItem and pass it back.
3995             Dim tb As TabPage = DirectCast(DirectCast(sender, Tween.TweenCustomControl.DetailsListView).Parent, TabPage)
3996             Try
3997                 e.Item = CreateItem(tb, _
3998                                     _statuses.Item(tb.Text, e.ItemIndex), _
3999                                     e.ItemIndex)
4000             Catch ex As Exception
4001                 '不正な要求に対する間に合わせの応答
4002                 Dim sitem() As String = {"", "", "", "", "", "", "", ""}
4003                 e.Item = New ImageListViewItem(sitem, "")
4004             End Try
4005         End If
4006     End Sub
4007
4008     Private Sub CreateCache(ByVal StartIndex As Integer, ByVal EndIndex As Integer)
4009         Try
4010             'キャッシュ要求(要求範囲±30を作成)
4011             StartIndex -= 30
4012             If StartIndex < 0 Then StartIndex = 0
4013             EndIndex += 30
4014             If EndIndex >= _statuses.Tabs(_curTab.Text).AllCount Then EndIndex = _statuses.Tabs(_curTab.Text).AllCount - 1
4015             _postCache = _statuses.Item(_curTab.Text, StartIndex, EndIndex) '配列で取得
4016             _itemCacheIndex = StartIndex
4017
4018             _itemCache = New ListViewItem(_postCache.Length - 1) {}
4019             For i As Integer = 0 To _postCache.Length - 1
4020                 _itemCache(i) = CreateItem(_curTab, _postCache(i), StartIndex + i)
4021             Next i
4022         Catch ex As Exception
4023             'キャッシュ要求が実データとずれるため(イベントの遅延?)
4024             _postCache = Nothing
4025             _itemCache = Nothing
4026         End Try
4027     End Sub
4028
4029     Private Function CreateItem(ByVal Tab As TabPage, ByVal Post As PostClass, ByVal Index As Integer) As ListViewItem
4030         Dim mk As New StringBuilder
4031         If Post.IsDeleted Then mk.Append("×")
4032         If Post.IsMark Then mk.Append("♪")
4033         If Post.IsProtect Then mk.Append("Ю")
4034         If Post.InReplyToStatusId > 0 Then mk.Append("⇒")
4035         If Post.FavoritedCount > 0 Then mk.Append("+" + Post.FavoritedCount.ToString)
4036         Dim itm As ImageListViewItem
4037         If Post.RetweetedId = 0 Then
4038             Dim sitem() As String = {"",
4039                                      Post.Nickname,
4040                                      If(Post.IsDeleted, "(DELETED)", Post.TextFromApi),
4041                                      Post.CreatedAt.ToString(SettingDialog.DateTimeFormat),
4042                                      Post.ScreenName,
4043                                      "",
4044                                      mk.ToString(),
4045                                      Post.Source}
4046             itm = New ImageListViewItem(sitem, DirectCast(Me.TIconDic, ImageDictionary), Post.ImageUrl)
4047         Else
4048             Dim sitem() As String = {"",
4049                                      Post.Nickname,
4050                                      If(Post.IsDeleted, "(DELETED)", Post.TextFromApi),
4051                                      Post.CreatedAt.ToString(SettingDialog.DateTimeFormat),
4052                                      Post.ScreenName + Environment.NewLine + "(RT:" + Post.RetweetedBy + ")",
4053                                      "",
4054                                      mk.ToString(),
4055                                      Post.Source}
4056             itm = New ImageListViewItem(sitem, DirectCast(Me.TIconDic, ImageDictionary), Post.ImageUrl)
4057         End If
4058
4059         Dim read As Boolean = Post.IsRead
4060         '未読管理していなかったら既読として扱う
4061         If Not _statuses.Tabs(Tab.Text).UnreadManage OrElse _
4062            Not SettingDialog.UnreadManage Then read = True
4063         ChangeItemStyleRead(read, itm, Post, Nothing)
4064         If Tab.Equals(_curTab) Then ColorizeList(itm, Index)
4065         Return itm
4066     End Function
4067
4068     Private Sub MyList_DrawColumnHeader(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs)
4069         e.DrawDefault = True
4070     End Sub
4071
4072     Private Sub MyList_HScrolled(ByVal sender As Object, ByVal e As EventArgs)
4073         Dim listView As DetailsListView = DirectCast(sender, DetailsListView)
4074         listView.Refresh()
4075     End Sub
4076
4077     Private Sub MyList_DrawItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawListViewItemEventArgs)
4078         If e.State = 0 Then Exit Sub
4079         e.DrawDefault = False
4080         If Not e.Item.Selected Then     'e.ItemStateでうまく判定できない???
4081             Dim brs2 As SolidBrush = Nothing
4082             Select Case e.Item.BackColor
4083                 Case _clSelf
4084                     brs2 = _brsBackColorMine
4085                 Case _clAtSelf
4086                     brs2 = _brsBackColorAt
4087                 Case _clTarget
4088                     brs2 = _brsBackColorYou
4089                 Case _clAtTarget
4090                     brs2 = _brsBackColorAtYou
4091                 Case _clAtFromTarget
4092                     brs2 = _brsBackColorAtFromTarget
4093                 Case _clAtTo
4094                     brs2 = _brsBackColorAtTo
4095                 Case Else
4096                     brs2 = _brsBackColorNone
4097             End Select
4098             e.Graphics.FillRectangle(brs2, e.Bounds)
4099         Else
4100             '選択中の行
4101             If DirectCast(sender, Windows.Forms.Control).Focused Then
4102                 e.Graphics.FillRectangle(_brsHighLight, e.Bounds)
4103             Else
4104                 e.Graphics.FillRectangle(_brsDeactiveSelection, e.Bounds)
4105             End If
4106         End If
4107         If (e.State And ListViewItemStates.Focused) = ListViewItemStates.Focused Then e.DrawFocusRectangle()
4108         Me.DrawListViewItemIcon(e)
4109     End Sub
4110
4111     Private Sub MyList_DrawSubItem(ByVal sender As Object, ByVal e As DrawListViewSubItemEventArgs)
4112         If e.ItemState = 0 Then Exit Sub
4113
4114         If e.ColumnIndex > 0 Then
4115             'アイコン以外の列
4116             Dim rct As RectangleF = e.Bounds
4117             Dim rctB As RectangleF = e.Bounds
4118             rct.Width = e.Header.Width
4119             rctB.Width = e.Header.Width
4120             If _iconCol Then
4121                 rct.Y += e.Item.Font.Height
4122                 rct.Height -= e.Item.Font.Height
4123                 rctB.Height = e.Item.Font.Height
4124             End If
4125
4126
4127             Dim heightDiff As Integer
4128             Dim drawLineCount As Integer = Math.Max(1, Math.DivRem(CType(rct.Height, Integer), e.Item.Font.Height, heightDiff))
4129
4130             'If heightDiff > e.Item.Font.Height * 0.7 Then
4131             '    rct.Height += e.Item.Font.Height
4132             '    drawLineCount += 1
4133             'End If
4134
4135             'フォントの高さの半分を足してるのは保険。無くてもいいかも。
4136             If Not _iconCol AndAlso drawLineCount <= 1 Then
4137                 'rct.Inflate(0, CType(heightDiff / -2, Integer))
4138                 'rct.Height += CType(e.Item.Font.Height / 2, Integer)
4139             ElseIf heightDiff < e.Item.Font.Height * 0.7 Then
4140                 '最終行が70%以上欠けていたら、最終行は表示しない
4141                 'rct.Height = CType((e.Item.Font.Height * drawLineCount) + (e.Item.Font.Height / 2), Single)
4142                 rct.Height = CType((e.Item.Font.Height * drawLineCount), Single) - 1
4143             Else
4144                 drawLineCount += 1
4145             End If
4146
4147             'If Not _iconCol AndAlso drawLineCount > 1 Then
4148             '    rct.Y += CType(e.Item.Font.Height * 0.2, Single)
4149             '    If heightDiff >= e.Item.Font.Height * 0.8 Then rct.Height -= CType(e.Item.Font.Height * 0.2, Single)
4150             'End If
4151             If Not e.Item.Selected Then     'e.ItemStateでうまく判定できない???
4152                 '選択されていない行
4153                 '文字色
4154                 Dim brs As SolidBrush = Nothing
4155                 Dim flg As Boolean = False
4156                 Select Case e.Item.ForeColor
4157                     Case _clUnread
4158                         brs = _brsForeColorUnread
4159                     Case _clReaded
4160                         brs = _brsForeColorReaded
4161                     Case _clFav
4162                         brs = _brsForeColorFav
4163                     Case _clOWL
4164                         brs = _brsForeColorOWL
4165                     Case _clRetweet
4166                         brs = _brsForeColorRetweet
4167                     Case Else
4168                         brs = New SolidBrush(e.Item.ForeColor)
4169                         flg = True
4170                 End Select
4171                 If rct.Width > 0 Then
4172                     If _iconCol Then
4173                         Using fnt As New Font(e.Item.Font, FontStyle.Bold)
4174                             'e.Graphics.DrawString(System.Environment.NewLine + e.Item.SubItems(2).Text, e.Item.Font, brs, rct, sf)
4175                             'e.Graphics.DrawString(e.Item.SubItems(4).Text + " / " + e.Item.SubItems(1).Text + " (" + e.Item.SubItems(3).Text + ") " + e.Item.SubItems(5).Text + e.Item.SubItems(6).Text + " [" + e.Item.SubItems(7).Text + "]", fnt, brs, rctB, sf)
4176                             TextRenderer.DrawText(e.Graphics,
4177                                                   e.Item.SubItems(2).Text,
4178                                                   e.Item.Font,
4179                                                   Rectangle.Round(rct),
4180                                                   brs.Color,
4181                                                   TextFormatFlags.WordBreak Or
4182                                                   TextFormatFlags.EndEllipsis Or
4183                                                   TextFormatFlags.GlyphOverhangPadding Or
4184                                                   TextFormatFlags.NoPrefix)
4185                             TextRenderer.DrawText(e.Graphics,
4186                                                   e.Item.SubItems(4).Text + " / " + e.Item.SubItems(1).Text + " (" + e.Item.SubItems(3).Text + ") " + e.Item.SubItems(5).Text + e.Item.SubItems(6).Text + " [" + e.Item.SubItems(7).Text + "]",
4187                                                   fnt,
4188                                                   Rectangle.Round(rctB),
4189                                                   brs.Color,
4190                                                   TextFormatFlags.SingleLine Or
4191                                                   TextFormatFlags.EndEllipsis Or
4192                                                   TextFormatFlags.GlyphOverhangPadding Or
4193                                                   TextFormatFlags.NoPrefix)
4194                         End Using
4195                     ElseIf drawLineCount = 1 Then
4196                         TextRenderer.DrawText(e.Graphics,
4197                                               e.SubItem.Text,
4198                                               e.Item.Font,
4199                                               Rectangle.Round(rct),
4200                                               brs.Color,
4201                                               TextFormatFlags.SingleLine Or
4202                                               TextFormatFlags.EndEllipsis Or
4203                                               TextFormatFlags.GlyphOverhangPadding Or
4204                                               TextFormatFlags.NoPrefix Or
4205                                               TextFormatFlags.VerticalCenter)
4206                     Else
4207                         'e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, brs, rct, sf)
4208                         TextRenderer.DrawText(e.Graphics,
4209                                               e.SubItem.Text,
4210                                               e.Item.Font,
4211                                               Rectangle.Round(rct),
4212                                               brs.Color,
4213                                               TextFormatFlags.WordBreak Or
4214                                               TextFormatFlags.EndEllipsis Or
4215                                               TextFormatFlags.GlyphOverhangPadding Or
4216                                               TextFormatFlags.NoPrefix)
4217                     End If
4218                 End If
4219                 If flg Then brs.Dispose()
4220             Else
4221                 If rct.Width > 0 Then
4222                     '選択中の行
4223                     Using fnt As New Font(e.Item.Font, FontStyle.Bold)
4224                         If DirectCast(sender, Windows.Forms.Control).Focused Then
4225                             If _iconCol Then
4226                                 'e.Graphics.DrawString(System.Environment.NewLine + e.Item.SubItems(2).Text, e.Item.Font, _brsHighLightText, rct, sf)
4227                                 'e.Graphics.DrawString(e.Item.SubItems(4).Text + " / " + e.Item.SubItems(1).Text + " (" + e.Item.SubItems(3).Text + ") " + e.Item.SubItems(5).Text + e.Item.SubItems(6).Text + " [" + e.Item.SubItems(7).Text + "]", fnt, _brsHighLightText, rctB, sf)
4228                                 TextRenderer.DrawText(e.Graphics,
4229                                                       e.Item.SubItems(2).Text,
4230                                                       e.Item.Font,
4231                                                       Rectangle.Round(rct),
4232                                                       _brsHighLightText.Color,
4233                                                       TextFormatFlags.WordBreak Or
4234                                                       TextFormatFlags.EndEllipsis Or
4235                                                       TextFormatFlags.GlyphOverhangPadding Or
4236                                                       TextFormatFlags.NoPrefix)
4237                                 TextRenderer.DrawText(e.Graphics,
4238                                                       e.Item.SubItems(4).Text + " / " + e.Item.SubItems(1).Text + " (" + e.Item.SubItems(3).Text + ") " + e.Item.SubItems(5).Text + e.Item.SubItems(6).Text + " [" + e.Item.SubItems(7).Text + "]",
4239                                                       fnt,
4240                                                       Rectangle.Round(rctB),
4241                                                       _brsHighLightText.Color,
4242                                                       TextFormatFlags.SingleLine Or
4243                                                       TextFormatFlags.EndEllipsis Or
4244                                                       TextFormatFlags.GlyphOverhangPadding Or
4245                                                       TextFormatFlags.NoPrefix)
4246                             ElseIf drawLineCount = 1 Then
4247                                 TextRenderer.DrawText(e.Graphics,
4248                                                       e.SubItem.Text,
4249                                                       e.Item.Font,
4250                                                       Rectangle.Round(rct),
4251                                                       _brsHighLightText.Color,
4252                                                       TextFormatFlags.SingleLine Or
4253                                                       TextFormatFlags.EndEllipsis Or
4254                                                       TextFormatFlags.GlyphOverhangPadding Or
4255                                                       TextFormatFlags.NoPrefix Or
4256                                                       TextFormatFlags.VerticalCenter)
4257                             Else
4258                                 'e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, _brsHighLightText, rct, sf)
4259                                 TextRenderer.DrawText(e.Graphics,
4260                                                       e.SubItem.Text,
4261                                                       e.Item.Font,
4262                                                       Rectangle.Round(rct),
4263                                                       _brsHighLightText.Color,
4264                                                       TextFormatFlags.WordBreak Or
4265                                                       TextFormatFlags.EndEllipsis Or
4266                                                       TextFormatFlags.GlyphOverhangPadding Or
4267                                                       TextFormatFlags.NoPrefix)
4268                             End If
4269                         Else
4270                             If _iconCol Then
4271                                 'e.Graphics.DrawString(System.Environment.NewLine + e.Item.SubItems(2).Text, e.Item.Font, _brsForeColorUnread, rct, sf)
4272                                 'e.Graphics.DrawString(e.Item.SubItems(4).Text + " / " + e.Item.SubItems(1).Text + " (" + e.Item.SubItems(3).Text + ") " + e.Item.SubItems(5).Text + e.Item.SubItems(6).Text + " [" + e.Item.SubItems(7).Text + "]", fnt, _brsForeColorUnread, rctB, sf)
4273                                 TextRenderer.DrawText(e.Graphics,
4274                                                       e.Item.SubItems(2).Text,
4275                                                       e.Item.Font,
4276                                                       Rectangle.Round(rct),
4277                                                       _brsForeColorUnread.Color,
4278                                                       TextFormatFlags.WordBreak Or
4279                                                       TextFormatFlags.EndEllipsis Or
4280                                                       TextFormatFlags.GlyphOverhangPadding Or
4281                                                       TextFormatFlags.NoPrefix)
4282                                 TextRenderer.DrawText(e.Graphics,
4283                                                       e.Item.SubItems(4).Text + " / " + e.Item.SubItems(1).Text + " (" + e.Item.SubItems(3).Text + ") " + e.Item.SubItems(5).Text + e.Item.SubItems(6).Text + " [" + e.Item.SubItems(7).Text + "]",
4284                                                       fnt,
4285                                                       Rectangle.Round(rctB),
4286                                                       _brsForeColorUnread.Color,
4287                                                       TextFormatFlags.SingleLine Or
4288                                                       TextFormatFlags.EndEllipsis Or
4289                                                       TextFormatFlags.GlyphOverhangPadding Or
4290                                                       TextFormatFlags.NoPrefix)
4291                             ElseIf drawLineCount = 1 Then
4292                                 TextRenderer.DrawText(e.Graphics,
4293                                                       e.SubItem.Text,
4294                                                       e.Item.Font,
4295                                                       Rectangle.Round(rct),
4296                                                       _brsForeColorUnread.Color,
4297                                                       TextFormatFlags.SingleLine Or
4298                                                       TextFormatFlags.EndEllipsis Or
4299                                                       TextFormatFlags.GlyphOverhangPadding Or
4300                                                       TextFormatFlags.NoPrefix Or
4301                                                       TextFormatFlags.VerticalCenter)
4302                             Else
4303                                 'e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, _brsForeColorUnread, rct, sf)
4304                                 TextRenderer.DrawText(e.Graphics,
4305                                                       e.SubItem.Text,
4306                                                       e.Item.Font,
4307                                                       Rectangle.Round(rct),
4308                                                       _brsForeColorUnread.Color,
4309                                                       TextFormatFlags.WordBreak Or
4310                                                       TextFormatFlags.EndEllipsis Or
4311                                                       TextFormatFlags.GlyphOverhangPadding Or
4312                                                       TextFormatFlags.NoPrefix)
4313                             End If
4314                         End If
4315                     End Using
4316                 End If
4317             End If
4318         End If
4319     End Sub
4320
4321     Private Sub DrawListViewItemIcon(ByVal e As DrawListViewItemEventArgs)
4322         Dim item As ImageListViewItem = DirectCast(e.Item, ImageListViewItem)
4323         If item.Image IsNot Nothing Then
4324             'e.Bounds.Leftが常に0を指すから自前で計算
4325             Dim itemRect As Rectangle = item.Bounds
4326             itemRect.Width = e.Item.ListView.Columns(0).Width
4327
4328             For Each clm As ColumnHeader In e.Item.ListView.Columns
4329                 If clm.DisplayIndex < e.Item.ListView.Columns(0).DisplayIndex Then
4330                     itemRect.X += clm.Width
4331                 End If
4332             Next
4333
4334             Dim iconRect As Rectangle = Rectangle.Intersect(New Rectangle(e.Item.GetBounds(ItemBoundsPortion.Icon).Location, New Size(_iconSz, _iconSz)), itemRect)
4335             iconRect.Offset(0, CType(Math.Max(0, (itemRect.Height - _iconSz) / 2), Integer))
4336
4337             If iconRect.Width > 0 Then
4338                 e.Graphics.FillRectangle(Brushes.White, iconRect)
4339                 e.Graphics.InterpolationMode = Drawing2D.InterpolationMode.High
4340                 Try
4341                     e.Graphics.DrawImage(item.Image, iconRect)
4342                 Catch ex As ArgumentException
4343                     item.RegetImage()
4344                 End Try
4345             End If
4346         End If
4347     End Sub
4348
4349     Private Sub DoTabSearch(ByVal _word As String, _
4350                             ByVal CaseSensitive As Boolean, _
4351                             ByVal UseRegex As Boolean, _
4352                             ByVal SType As SEARCHTYPE)
4353         Dim cidx As Integer = 0
4354         Dim fnd As Boolean = False
4355         Dim toIdx As Integer
4356         Dim stp As Integer = 1
4357
4358         If _curList.VirtualListSize = 0 Then
4359             MessageBox.Show(My.Resources.DoTabSearchText2, My.Resources.DoTabSearchText3, MessageBoxButtons.OK, MessageBoxIcon.Information)
4360         End If
4361
4362         If _curList.SelectedIndices.Count > 0 Then
4363             cidx = _curList.SelectedIndices(0)
4364         End If
4365         toIdx = _curList.VirtualListSize - 1
4366
4367         Select Case SType
4368             Case SEARCHTYPE.DialogSearch    'ダイアログからの検索
4369                 If _curList.SelectedIndices.Count > 0 Then
4370                     cidx = _curList.SelectedIndices(0)
4371                 Else
4372                     cidx = 0
4373                 End If
4374             Case SEARCHTYPE.NextSearch      '次を検索
4375                 If _curList.SelectedIndices.Count > 0 Then
4376                     cidx = _curList.SelectedIndices(0) + 1
4377                     If cidx > toIdx Then cidx = toIdx
4378                 Else
4379                     cidx = 0
4380                 End If
4381             Case SEARCHTYPE.PrevSearch      '前を検索
4382                 If _curList.SelectedIndices.Count > 0 Then
4383                     cidx = _curList.SelectedIndices(0) - 1
4384                     If cidx < 0 Then cidx = 0
4385                 Else
4386                     cidx = toIdx
4387                 End If
4388                 toIdx = 0
4389                 stp = -1
4390         End Select
4391
4392         Dim regOpt As RegexOptions = RegexOptions.None
4393         Dim fndOpt As StringComparison = StringComparison.Ordinal
4394         If Not CaseSensitive Then
4395             regOpt = RegexOptions.IgnoreCase
4396             fndOpt = StringComparison.OrdinalIgnoreCase
4397         End If
4398         Try
4399 RETRY:
4400             If UseRegex Then
4401                 ' 正規表現検索
4402                 Dim _search As Regex
4403                 Try
4404                     _search = New Regex(_word)
4405                     For idx As Integer = cidx To toIdx Step stp
4406                         Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
4407                         If _search.IsMatch(post.Nickname, regOpt) _
4408                             OrElse _search.IsMatch(post.TextFromApi, regOpt) _
4409                             OrElse _search.IsMatch(post.ScreenName, regOpt) _
4410                         Then
4411                             SelectListItem(_curList, idx)
4412                             _curList.EnsureVisible(idx)
4413                             Exit Sub
4414                         End If
4415                     Next
4416                 Catch ex As ArgumentException
4417                     MsgBox(My.Resources.DoTabSearchText1, MsgBoxStyle.Critical)
4418                     Exit Sub
4419                 End Try
4420             Else
4421                 ' 通常検索
4422                 For idx As Integer = cidx To toIdx Step stp
4423                     Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
4424                     If post.Nickname.IndexOf(_word, fndOpt) > -1 _
4425                         OrElse post.TextFromApi.IndexOf(_word, fndOpt) > -1 _
4426                         OrElse post.ScreenName.IndexOf(_word, fndOpt) > -1 _
4427                     Then
4428                         SelectListItem(_curList, idx)
4429                         _curList.EnsureVisible(idx)
4430                         Exit Sub
4431                     End If
4432                 Next
4433             End If
4434
4435             If Not fnd Then
4436                 Select Case SType
4437                     Case SEARCHTYPE.DialogSearch, SEARCHTYPE.NextSearch
4438                         toIdx = cidx
4439                         cidx = 0
4440                     Case SEARCHTYPE.PrevSearch
4441                         toIdx = cidx
4442                         cidx = _curList.Items.Count - 1
4443                 End Select
4444                 fnd = True
4445                 GoTo RETRY
4446             End If
4447         Catch ex As ArgumentOutOfRangeException
4448
4449         End Try
4450         MessageBox.Show(My.Resources.DoTabSearchText2, My.Resources.DoTabSearchText3, MessageBoxButtons.OK, MessageBoxIcon.Information)
4451     End Sub
4452
4453     Private Sub MenuItemSubSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemSubSearch.Click
4454         '検索メニュー
4455         SearchDialog.Owner = Me
4456         If SearchDialog.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
4457             Me.TopMost = SettingDialog.AlwaysTop
4458             Exit Sub
4459         End If
4460         Me.TopMost = SettingDialog.AlwaysTop
4461
4462         If SearchDialog.SWord <> "" Then
4463             DoTabSearch(SearchDialog.SWord, _
4464                         SearchDialog.CheckCaseSensitive, _
4465                         SearchDialog.CheckRegex, _
4466                         SEARCHTYPE.DialogSearch)
4467         End If
4468     End Sub
4469
4470     Private Sub MenuItemSearchNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemSearchNext.Click
4471         '次を検索
4472         If SearchDialog.SWord = "" Then
4473             If SearchDialog.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
4474                 Me.TopMost = SettingDialog.AlwaysTop
4475                 Exit Sub
4476             End If
4477             Me.TopMost = SettingDialog.AlwaysTop
4478             If SearchDialog.SWord = "" Then Exit Sub
4479
4480             DoTabSearch(SearchDialog.SWord, _
4481                         SearchDialog.CheckCaseSensitive, _
4482                         SearchDialog.CheckRegex, _
4483                         SEARCHTYPE.DialogSearch)
4484         Else
4485             DoTabSearch(SearchDialog.SWord, _
4486                         SearchDialog.CheckCaseSensitive, _
4487                         SearchDialog.CheckRegex, _
4488                         SEARCHTYPE.NextSearch)
4489         End If
4490     End Sub
4491
4492     Private Sub MenuItemSearchPrev_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemSearchPrev.Click
4493         '前を検索
4494         If SearchDialog.SWord = "" Then
4495             If SearchDialog.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
4496                 Me.TopMost = SettingDialog.AlwaysTop
4497                 Exit Sub
4498             End If
4499             Me.TopMost = SettingDialog.AlwaysTop
4500             If SearchDialog.SWord = "" Then Exit Sub
4501         End If
4502
4503         DoTabSearch(SearchDialog.SWord, _
4504                     SearchDialog.CheckCaseSensitive, _
4505                     SearchDialog.CheckRegex, _
4506                     SEARCHTYPE.PrevSearch)
4507     End Sub
4508
4509     Private Sub AboutMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AboutMenuItem.Click
4510         TweenAboutBox.ShowDialog()
4511         Me.TopMost = SettingDialog.AlwaysTop
4512     End Sub
4513
4514     Private Sub JumpUnreadMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles JumpUnreadMenuItem.Click, JumpReadOpMenuItem.Click
4515         Dim bgnIdx As Integer = ListTab.TabPages.IndexOf(_curTab)
4516         Dim idx As Integer = -1
4517         Dim lst As DetailsListView = Nothing
4518
4519         If ImageSelectionPanel.Enabled Then
4520             Exit Sub
4521         End If
4522
4523         '現在タブから最終タブまで探索
4524         For i As Integer = bgnIdx To ListTab.TabPages.Count - 1
4525             '未読Index取得
4526             idx = _statuses.GetOldestUnreadIndex(ListTab.TabPages(i).Text)
4527             If idx > -1 Then
4528                 ListTab.SelectedIndex = i
4529                 lst = DirectCast(ListTab.TabPages(i).Tag, DetailsListView)
4530                 '_curTab = ListTab.TabPages(i)
4531                 Exit For
4532             End If
4533         Next
4534
4535         '未読みつからず&現在タブが先頭ではなかったら、先頭タブから現在タブの手前まで探索
4536         If idx = -1 AndAlso bgnIdx > 0 Then
4537             For i As Integer = 0 To bgnIdx - 1
4538                 idx = _statuses.GetOldestUnreadIndex(ListTab.TabPages(i).Text)
4539                 If idx > -1 Then
4540                     ListTab.SelectedIndex = i
4541                     lst = DirectCast(ListTab.TabPages(i).Tag, DetailsListView)
4542                     '_curTab = ListTab.TabPages(i)
4543                     Exit For
4544                 End If
4545             Next
4546         End If
4547
4548         '全部調べたが未読見つからず→先頭タブの最新発言へ
4549         If idx = -1 Then
4550             ListTab.SelectedIndex = 0
4551             lst = DirectCast(ListTab.TabPages(0).Tag, DetailsListView)
4552             '_curTab = ListTab.TabPages(0)
4553             If _statuses.SortOrder = SortOrder.Ascending Then
4554                 idx = lst.VirtualListSize - 1
4555             Else
4556                 idx = 0
4557             End If
4558         End If
4559
4560         If lst.VirtualListSize > 0 AndAlso idx > -1 AndAlso lst.VirtualListSize > idx Then
4561             SelectListItem(lst, idx)
4562             If _statuses.SortMode = IdComparerClass.ComparerMode.Id Then
4563                 If _statuses.SortOrder = SortOrder.Ascending AndAlso lst.Items(idx).Position.Y > lst.ClientSize.Height - _iconSz - 10 OrElse _
4564                    _statuses.SortOrder = SortOrder.Descending AndAlso lst.Items(idx).Position.Y < _iconSz + 10 Then
4565                     MoveTop()
4566                 Else
4567                     lst.EnsureVisible(idx)
4568                 End If
4569             Else
4570                 lst.EnsureVisible(idx)
4571             End If
4572         End If
4573         lst.Focus()
4574     End Sub
4575
4576     Private Sub StatusOpenMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusOpenMenuItem.Click, OpenStatusOpMenuItem.Click
4577         If _curList.SelectedIndices.Count > 0 AndAlso _statuses.Tabs(_curTab.Text).TabType <> TabUsageType.DirectMessage Then
4578             Dim post As PostClass = _statuses.Item(_curTab.Text, _curList.SelectedIndices(0))
4579             If post.RetweetedId = 0 Then
4580                 OpenUriAsync("http://twitter.com/" + post.ScreenName + "/status/" + post.StatusId.ToString)
4581             Else
4582                 OpenUriAsync("http://twitter.com/" + post.ScreenName + "/status/" + post.RetweetedId.ToString)
4583             End If
4584         End If
4585     End Sub
4586
4587     Private Sub FavorareMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles FavorareMenuItem.Click, OpenFavotterOpMenuItem.Click
4588         If _curList.SelectedIndices.Count > 0 Then
4589             Dim post As PostClass = _statuses.Item(_curTab.Text, _curList.SelectedIndices(0))
4590             OpenUriAsync(My.Resources.FavstarUrl + "users/" + post.ScreenName + "/recent")
4591         End If
4592     End Sub
4593
4594     Private Sub VerUpMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles VerUpMenuItem.Click
4595         CheckNewVersion()
4596     End Sub
4597
4598     Private Sub RunTweenUp()
4599
4600         Dim pinfo As New ProcessStartInfo
4601         pinfo.UseShellExecute = True
4602         pinfo.WorkingDirectory = Application.StartupPath
4603         pinfo.FileName = Path.Combine(Application.StartupPath(), "TweenUp2.exe")
4604         Try
4605             Process.Start(pinfo)
4606         Catch ex As Exception
4607             MessageBox.Show("Failed to execute TweenUp2.exe.")
4608         End Try
4609     End Sub
4610
4611     Private Sub CheckNewVersion(Optional ByVal startup As Boolean = False)
4612         Dim retMsg As String = ""
4613         Dim strVer As String = ""
4614         Dim strDetail As String = ""
4615         Dim forceUpdate As Boolean = My.Computer.Keyboard.ShiftKeyDown
4616
4617         Try
4618             retMsg = tw.GetVersionInfo()
4619         Catch ex As Exception
4620             StatusLabel.Text = My.Resources.CheckNewVersionText9
4621             If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText10, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2)
4622             Exit Sub
4623         End Try
4624         If retMsg.Length > 0 Then
4625             strVer = retMsg.Substring(0, 4)
4626             If retMsg.Length > 4 Then
4627                 strDetail = retMsg.Substring(5).Trim
4628             End If
4629             If fileVersion <> "" AndAlso strVer.CompareTo(fileVersion.Replace(".", "")) > 0 Then
4630                 Dim tmp As String = String.Format(My.Resources.CheckNewVersionText3, strVer)
4631                 Using dialogAsShieldicon As New DialogAsShieldIcon
4632                     If dialogAsShieldicon.Show(tmp, strDetail, My.Resources.CheckNewVersionText1, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
4633                         retMsg = tw.GetTweenBinary(strVer)
4634                         If retMsg.Length = 0 Then
4635                             RunTweenUp()
4636                             _endingFlag = True
4637                             dialogAsShieldicon.Dispose()
4638                             Me.Close()
4639                             Exit Sub
4640                         Else
4641                             If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText5 + System.Environment.NewLine + retMsg, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
4642                         End If
4643                     End If
4644                     dialogAsShieldicon.Dispose()
4645                 End Using
4646             Else
4647                 If forceUpdate Then
4648                     Dim tmp As String = String.Format(My.Resources.CheckNewVersionText6, strVer)
4649                     Using dialogAsShieldicon As New DialogAsShieldIcon
4650                         If dialogAsShieldicon.Show(tmp, strDetail, My.Resources.CheckNewVersionText1, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
4651                             retMsg = tw.GetTweenBinary(strVer)
4652                             If retMsg.Length = 0 Then
4653                                 RunTweenUp()
4654                                 _endingFlag = True
4655                                 dialogAsShieldicon.Dispose()
4656                                 Me.Close()
4657                                 Exit Sub
4658                             Else
4659                                 If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText5 + System.Environment.NewLine + retMsg, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
4660                             End If
4661                         End If
4662                         dialogAsShieldicon.Dispose()
4663                     End Using
4664                 ElseIf Not startup Then
4665                     MessageBox.Show(My.Resources.CheckNewVersionText7 + fileVersion.Replace(".", "") + My.Resources.CheckNewVersionText8 + strVer, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Information)
4666                 End If
4667             End If
4668         Else
4669             StatusLabel.Text = My.Resources.CheckNewVersionText9
4670             If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText10, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
4671         End If
4672     End Sub
4673
4674     Private Sub Colorize()
4675         _colorize = False
4676         DispSelectedPost()
4677         '件数関連の場合、タイトル即時書き換え
4678         If SettingDialog.DispLatestPost <> DispTitleEnum.None AndAlso _
4679            SettingDialog.DispLatestPost <> DispTitleEnum.Post AndAlso _
4680            SettingDialog.DispLatestPost <> DispTitleEnum.Ver AndAlso _
4681            SettingDialog.DispLatestPost <> DispTitleEnum.OwnStatus Then
4682             SetMainWindowTitle()
4683         End If
4684         If Not StatusLabelUrl.Text.StartsWith("http") Then SetStatusLabelUrl()
4685         For Each tb As TabPage In ListTab.TabPages
4686             If _statuses.Tabs(tb.Text).UnreadCount = 0 Then
4687                 If SettingDialog.TabIconDisp Then
4688                     If tb.ImageIndex = 0 Then tb.ImageIndex = -1
4689                 End If
4690             End If
4691         Next
4692         If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
4693     End Sub
4694
4695     Public Function createDetailHtml(ByVal orgdata As String) As String
4696         Return detailHtmlFormatHeader + orgdata + detailHtmlFormatFooter
4697     End Function
4698
4699     Private Sub DisplayItemImage_Downloaded(ByVal sender As Object, ByVal e As EventArgs) Handles displayItem.ImageDownloaded
4700         If sender.Equals(displayItem) Then
4701             If UserPicture.Image IsNot Nothing Then UserPicture.Image.Dispose()
4702             If displayItem.Image IsNot Nothing Then
4703                 Try
4704                     UserPicture.Image = New Bitmap(displayItem.Image)
4705                 Catch ex As Exception
4706                     UserPicture.Image = Nothing
4707                 End Try
4708             Else
4709                 UserPicture.Image = Nothing
4710             End If
4711         End If
4712     End Sub
4713
4714     Private Overloads Sub DispSelectedPost()
4715         DispSelectedPost(False)
4716     End Sub
4717
4718     Private Overloads Sub DispSelectedPost(ByVal forceupdate As Boolean)
4719         Static displaypost As New PostClass
4720         If _curList.SelectedIndices.Count = 0 OrElse _
4721             _curPost Is Nothing Then Exit Sub
4722
4723         If Not forceupdate AndAlso _curPost.Equals(displaypost) Then
4724             Exit Sub
4725         End If
4726
4727         displaypost = _curPost
4728         displayItem = DirectCast(_curList.Items(_curList.SelectedIndices(0)), ImageListViewItem)
4729
4730         Dim dTxt As String = createDetailHtml(If(_curPost.IsDeleted, "(DELETED)", _curPost.Text))
4731         If _curPost.IsDm Then
4732             SourceLinkLabel.Tag = Nothing
4733             SourceLinkLabel.Text = ""
4734         Else
4735             Dim mc As Match = Regex.Match(_curPost.SourceHtml, "<a href=""(?<sourceurl>.+?)""")
4736             If mc.Success Then
4737                 Dim src As String = mc.Groups("sourceurl").Value
4738                 SourceLinkLabel.Tag = mc.Groups("sourceurl").Value
4739                 mc = Regex.Match(src, "^https?://")
4740                 If Not mc.Success Then
4741                     src = src.Insert(0, "http://twitter.com")
4742                 End If
4743                 SourceLinkLabel.Tag = src
4744             Else
4745                 SourceLinkLabel.Tag = Nothing
4746             End If
4747             If String.IsNullOrEmpty(_curPost.Source) Then
4748                 SourceLinkLabel.Text = ""
4749                 'SourceLinkLabel.Visible = False
4750             Else
4751                 SourceLinkLabel.Text = _curPost.Source
4752                 'SourceLinkLabel.Visible = True
4753             End If
4754         End If
4755         SourceLinkLabel.TabStop = False
4756
4757         If _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage AndAlso Not _curPost.IsOwl Then
4758             NameLabel.Text = "DM TO -> "
4759         ElseIf _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage Then
4760             NameLabel.Text = "DM FROM <- "
4761         Else
4762             NameLabel.Text = ""
4763         End If
4764         NameLabel.Text += _curPost.ScreenName + "/" + _curPost.Nickname
4765         NameLabel.Tag = _curPost.ScreenName
4766         If Not String.IsNullOrEmpty(_curPost.RetweetedBy) Then
4767             NameLabel.Text += " (RT:" + _curPost.RetweetedBy + ")"
4768         End If
4769         If UserPicture.Image IsNot Nothing Then UserPicture.Image.Dispose()
4770         If Not String.IsNullOrEmpty(_curPost.ImageUrl) AndAlso TIconDic(_curPost.ImageUrl) IsNot Nothing Then
4771             Try
4772                 UserPicture.Image = New Bitmap(TIconDic(_curPost.ImageUrl))
4773             Catch ex As Exception
4774                 UserPicture.Image = Nothing
4775             End Try
4776         Else
4777             UserPicture.Image = Nothing
4778         End If
4779
4780         NameLabel.ForeColor = System.Drawing.SystemColors.ControlText
4781         DateTimeLabel.Text = _curPost.CreatedAt.ToString()
4782         If _curPost.IsOwl AndAlso (SettingDialog.OneWayLove OrElse _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage) Then NameLabel.ForeColor = _clOWL
4783         If _curPost.RetweetedId > 0 Then NameLabel.ForeColor = _clRetweet
4784         If _curPost.IsFav Then NameLabel.ForeColor = _clFav
4785
4786         If DumpPostClassToolStripMenuItem.Checked Then
4787             Dim sb As New StringBuilder(512)
4788
4789             sb.Append("-----Start PostClass Dump<br>")
4790             sb.AppendFormat("TextFromApi           : {0}<br>", _curPost.TextFromApi)
4791             sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.TextFromApi)
4792             sb.AppendFormat("StatusId             : {0}<br>", _curPost.StatusId.ToString)
4793             'sb.AppendFormat("ImageIndex     : {0}<br>", _curPost.ImageIndex.ToString)
4794             sb.AppendFormat("ImageUrl       : {0}<br>", _curPost.ImageUrl)
4795             sb.AppendFormat("InReplyToStatusId    : {0}<br>", _curPost.InReplyToStatusId.ToString)
4796             sb.AppendFormat("InReplyToUser  : {0}<br>", _curPost.InReplyToUser)
4797             sb.AppendFormat("IsDM           : {0}<br>", _curPost.IsDm.ToString)
4798             sb.AppendFormat("IsFav          : {0}<br>", _curPost.IsFav.ToString)
4799             sb.AppendFormat("IsMark         : {0}<br>", _curPost.IsMark.ToString)
4800             sb.AppendFormat("IsMe           : {0}<br>", _curPost.IsMe.ToString)
4801             sb.AppendFormat("IsOwl          : {0}<br>", _curPost.IsOwl.ToString)
4802             sb.AppendFormat("IsProtect      : {0}<br>", _curPost.IsProtect.ToString)
4803             sb.AppendFormat("IsRead         : {0}<br>", _curPost.IsRead.ToString)
4804             sb.AppendFormat("IsReply        : {0}<br>", _curPost.IsReply.ToString)
4805
4806             For Each nm As String In _curPost.ReplyToList
4807                 sb.AppendFormat("ReplyToList    : {0}<br>", nm)
4808             Next
4809
4810             sb.AppendFormat("ScreenName           : {0}<br>", _curPost.ScreenName)
4811             sb.AppendFormat("NickName       : {0}<br>", _curPost.Nickname)
4812             sb.AppendFormat("Text   : {0}<br>", _curPost.Text)
4813             sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.Text)
4814             sb.AppendFormat("CreatedAt          : {0}<br>", _curPost.CreatedAt.ToString)
4815             sb.AppendFormat("Source         : {0}<br>", _curPost.Source)
4816             sb.AppendFormat("UserId            : {0}<br>", _curPost.UserId)
4817             sb.AppendFormat("FilterHit      : {0}<br>", _curPost.FilterHit)
4818             sb.AppendFormat("RetweetedBy    : {0}<br>", _curPost.RetweetedBy)
4819             sb.AppendFormat("RetweetedId    : {0}<br>", _curPost.RetweetedId)
4820             sb.AppendFormat("SearchTabName  : {0}<br>", _curPost.RelTabName)
4821             sb.Append("-----End PostClass Dump<br>")
4822
4823             PostBrowser.Visible = False
4824             PostBrowser.DocumentText = detailHtmlFormatHeader + sb.ToString + detailHtmlFormatFooter
4825             PostBrowser.Visible = True
4826         Else
4827             Try
4828                 If PostBrowser.DocumentText <> dTxt Then
4829                     PostBrowser.Visible = False
4830                     PostBrowser.DocumentText = dTxt
4831                     Dim lnks As New List(Of String)
4832                     For Each lnk As Match In Regex.Matches(dTxt, "<a target=""_self"" href=""(?<url>http[^""]+)""", RegexOptions.IgnoreCase)
4833                         lnks.Add(lnk.Result("${url}"))
4834                     Next
4835                     Thumbnail.thumbnail(_curPost.StatusId, lnks)
4836                 End If
4837             Catch ex As System.Runtime.InteropServices.COMException
4838                 '原因不明
4839             Finally
4840                 PostBrowser.Visible = True
4841             End Try
4842         End If
4843     End Sub
4844
4845     Private Sub MatomeMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MatomeMenuItem.Click
4846         OpenUriAsync("http://sourceforge.jp/projects/tween/wiki/FrontPage")
4847     End Sub
4848
4849     Private Sub ShortcutKeyListMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ShortcutKeyListMenuItem.Click
4850         OpenUriAsync("http://sourceforge.jp/projects/tween/wiki/%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88%E3%82%AD%E3%83%BC")
4851     End Sub
4852
4853     Private Sub ListTab_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles ListTab.KeyDown
4854         If ListTab.SelectedTab IsNot Nothing Then
4855             If _statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.PublicSearch Then
4856                 Dim pnl As Control = ListTab.SelectedTab.Controls("panelSearch")
4857                 If pnl.Controls("comboSearch").Focused OrElse _
4858                    pnl.Controls("comboLang").Focused OrElse _
4859                    pnl.Controls("buttonSearch").Focused Then Exit Sub
4860             End If
4861             Dim State As ModifierState = GetModifierState(e.Control, e.Shift, e.Alt)
4862             If State = ModifierState.NotFlags Then Exit Sub
4863             If State <> ModifierState.Non Then _anchorFlag = False
4864             If CommonKeyDown(e.KeyCode, ModifierState.ListTab, State) Then
4865                 e.Handled = True
4866                 e.SuppressKeyPress = True
4867             End If
4868         End If
4869
4870     End Sub
4871
4872     Public Function GetModifierState(ByVal sControl As Boolean, ByVal sShift As Boolean, ByVal sAlt As Boolean) As ModifierState
4873         If Not sAlt AndAlso Not sControl AndAlso Not sShift Then Return ModifierState.Non
4874         If sControl Then
4875             If sShift AndAlso Not sAlt Then
4876                 Return ModifierState.CShift
4877             ElseIf sAlt AndAlso Not sShift Then
4878                 Return ModifierState.CAlt
4879             ElseIf Not sAlt AndAlso Not sShift Then
4880                 Return ModifierState.Ctrl
4881             End If
4882         ElseIf sShift Then
4883             If sAlt AndAlso Not sControl Then
4884                 Return ModifierState.AShift
4885             ElseIf Not sAlt AndAlso Not sControl Then
4886                 Return ModifierState.Shift
4887             End If
4888         ElseIf sAlt Then
4889             If Not sControl AndAlso Not sShift Then Return ModifierState.Alt
4890         End If
4891         Return ModifierState.NotFlags
4892     End Function
4893
4894     Public Enum ModifierState As Integer
4895         Non = 0
4896         Alt = 1
4897         Shift = 2
4898         Ctrl = 3
4899         CShift = 11
4900         CAlt = 12
4901         AShift = 13
4902         NotFlags = 20
4903
4904         ListTab = 101
4905         PostBrowser = 102
4906         StatusText = 103
4907     End Enum
4908
4909     Public Function CommonKeyDown(ByVal KeyCode As System.Windows.Forms.Keys, ByVal Focused As ModifierState, ByVal Modifier As ModifierState) As Boolean
4910         Dim Pressed As Boolean = False
4911
4912         '修飾キーなし
4913         If Modifier = ModifierState.Non Then
4914             If KeyCode = Keys.F1 Then
4915                 Pressed = True
4916                 OpenUriAsync("http://sourceforge.jp/projects/tween/wiki/FrontPage")
4917             ElseIf KeyCode = Keys.F3 Then
4918                 Pressed = True
4919                 MenuItemSearchNext_Click(Nothing, Nothing)
4920             ElseIf KeyCode = Keys.F5 Then
4921                 Pressed = True
4922                 DoRefresh()
4923             ElseIf KeyCode = Keys.F6 Then
4924                 Pressed = True
4925                 GetTimeline(WORKERTYPE.Reply, 1, 0, "")
4926             ElseIf KeyCode = Keys.F7 Then
4927                 Pressed = True
4928                 GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0, "")
4929             End If
4930             If Focused <> ModifierState.StatusText AndAlso Not Pressed Then
4931                 If KeyCode = Keys.Space OrElse KeyCode = Keys.ProcessKey Then
4932                     Pressed = True
4933                     If Focused = ModifierState.ListTab Then _anchorFlag = False
4934                     JumpUnreadMenuItem_Click(Nothing, Nothing)
4935                 ElseIf KeyCode = Keys.G Then
4936                     Pressed = True
4937                     If Focused = ModifierState.ListTab Then _anchorFlag = False
4938                     ShowRelatedStatusesMenuItem_Click(Nothing, Nothing)
4939                 End If
4940             End If
4941             If Focused = ModifierState.ListTab AndAlso Not Pressed Then
4942                 If KeyCode = Keys.N OrElse KeyCode = Keys.Right Then
4943                     Pressed = True
4944                     GoRelPost(True)
4945                     Return Pressed
4946                 ElseIf KeyCode = Keys.P OrElse KeyCode = Keys.Left Then
4947                     Pressed = True
4948                     GoRelPost(False)
4949                     Return Pressed
4950                 ElseIf KeyCode = Keys.OemPeriod Then
4951                     Pressed = True
4952                     GoAnchor()
4953                     Return Pressed
4954                 End If
4955                 _anchorFlag = False
4956                 If KeyCode = Keys.Enter OrElse KeyCode = Keys.Return Then
4957                     Pressed = True
4958                     MakeReplyOrDirectStatus()
4959                 ElseIf KeyCode = Keys.L Then
4960                     Pressed = True
4961                     GoPost(True)
4962                 ElseIf KeyCode = Keys.H Then
4963                     Pressed = True
4964                     GoPost(False)
4965                 ElseIf KeyCode = Keys.J Then
4966                     Pressed = True
4967                     SendKeys.Send("{DOWN}")
4968                 ElseIf KeyCode = Keys.K Then
4969                     Pressed = True
4970                     SendKeys.Send("{UP}")
4971                 End If
4972                 If KeyCode = Keys.Z Or KeyCode = Keys.Oemcomma Then
4973                     Pressed = True
4974                     MoveTop()
4975                 ElseIf KeyCode = Keys.R Then
4976                     Pressed = True
4977                     DoRefresh()
4978                 ElseIf KeyCode = Keys.S Then
4979                     Pressed = True
4980                     GoNextTab(True)
4981                 ElseIf KeyCode = Keys.A Then
4982                     Pressed = True
4983                     GoNextTab(False)
4984                 End If
4985                 'If keycode = Keys.OemQuestion Then
4986                 '    Pressed=true    
4987                 '    MenuItemSubSearch_Click(Nothing, Nothing)   '/検索
4988                 'End If
4989                 If KeyCode = Keys.F Then
4990                     Pressed = True
4991                     SendKeys.Send("{PGDN}")
4992                 End If
4993                 If KeyCode = Keys.B Then
4994                     Pressed = True
4995                     SendKeys.Send("{PGUP}")
4996                 End If
4997                 If KeyCode = Keys.I Then
4998                     Pressed = True
4999                     'SendKeys.Send("{TAB}")
5000                     If Me.StatusText.Enabled Then Me.StatusText.Focus()
5001                 End If
5002                 ' ] in_reply_to参照元へ戻る
5003                 If KeyCode = Keys.Oem4 Then
5004                     Pressed = True
5005                     GoInReplyToPostTree()
5006                 End If
5007                 ' [ in_reply_toへジャンプ
5008                 If KeyCode = Keys.Oem6 Then
5009                     Pressed = True
5010                     GoBackInReplyToPostTree()
5011                 End If
5012                 If KeyCode = Keys.Escape Then
5013                     If ListTab.SelectedTab IsNot Nothing Then
5014                         Dim tabtype As TabUsageType = _statuses.Tabs(ListTab.SelectedTab.Text).TabType
5015                         If tabtype = TabUsageType.Related OrElse tabtype = TabUsageType.UserTimeline Then
5016                             Dim relTp As TabPage = ListTab.SelectedTab
5017                             RemoveSpecifiedTab(relTp.Text, False)
5018                             SaveConfigsTabs()
5019                         End If
5020                     End If
5021                 End If
5022             End If
5023             Return Pressed
5024         End If
5025
5026         'Ctrl+何か
5027         If Modifier = ModifierState.Ctrl Then
5028             If KeyCode = Keys.R Then
5029                 Pressed = True
5030                 MakeReplyOrDirectStatus(False, True)
5031             ElseIf KeyCode = Keys.D Then
5032                 Pressed = True
5033                 doStatusDelete()
5034             ElseIf KeyCode = Keys.M Then
5035                 Pressed = True
5036                 MakeReplyOrDirectStatus(False, False)
5037             ElseIf KeyCode = Keys.S Then
5038                 Pressed = True
5039                 FavoriteChange(True)
5040             ElseIf KeyCode = Keys.I Then
5041                 Pressed = True
5042                 doRepliedStatusOpen()
5043             ElseIf KeyCode = Keys.Q Then
5044                 Pressed = True
5045                 doQuote()
5046             ElseIf KeyCode = Keys.B Then
5047                 Pressed = True
5048                 ReadedStripMenuItem_Click(Nothing, Nothing)
5049             ElseIf KeyCode = Keys.T Then
5050                 Pressed = True
5051                 HashManageMenuItem_Click(Nothing, Nothing)
5052             ElseIf KeyCode = Keys.L Then
5053                 Pressed = True
5054                 UrlConvertAutoToolStripMenuItem_Click(Nothing, Nothing)
5055             ElseIf KeyCode = Keys.Y AndAlso Not Focused = ModifierState.PostBrowser Then
5056                 Pressed = True
5057                 MultiLineMenuItem_Click(Nothing, Nothing)
5058             ElseIf KeyCode = Keys.F Then
5059                 Pressed = True
5060                 MenuItemSubSearch_Click(Nothing, Nothing)
5061             ElseIf KeyCode = Keys.U Then
5062                 Pressed = True
5063                 ShowUserTimeline()
5064             End If
5065
5066
5067             ' Webページを開く動作
5068
5069             Select Case KeyCode
5070                 Case Keys.H
5071                     If _curList.SelectedIndices.Count > 0 Then
5072                         OpenUriAsync("http://twitter.com/" + GetCurTabPost(_curList.SelectedIndices(0)).ScreenName)
5073                     ElseIf _curList.SelectedIndices.Count = 0 Then
5074                         OpenUriAsync("http://twitter.com/")
5075                     End If
5076                 Case Keys.G
5077                     If _curList.SelectedIndices.Count > 0 Then
5078                         OpenUriAsync("http://twitter.com/" + GetCurTabPost(_curList.SelectedIndices(0)).ScreenName + "/favorites")
5079                     End If
5080                 Case Keys.O
5081                     StatusOpenMenuItem_Click(Nothing, Nothing)
5082                 Case Keys.E
5083                     OpenURLMenuItem_Click(Nothing, Nothing)
5084             End Select
5085             If Not Pressed Then
5086                 If Focused = ModifierState.ListTab Then
5087                     If KeyCode = Keys.Home OrElse KeyCode = Keys.End Then
5088                         _colorize = True
5089                     End If
5090                     If KeyCode = Keys.N Then
5091                         Pressed = True
5092                         GoNextTab(True)
5093                     ElseIf KeyCode = Keys.P Then
5094                         Pressed = True
5095                         GoNextTab(False)
5096                     ElseIf KeyCode = Keys.C Then
5097                         Dim clstr As String = ""
5098                         Pressed = True
5099                         CopyStot()
5100                     End If
5101
5102
5103                     ' タブダイレクト選択(Ctrl+1~8,Ctrl+9)
5104
5105                     Select Case KeyCode
5106                         Case Keys.D1, Keys.D2, Keys.D3, Keys.D4, Keys.D5, Keys.D6, Keys.D7, Keys.D8
5107                             Dim tabNo As Integer = KeyCode - Keys.D1
5108                             If ListTab.TabPages.Count < tabNo Then
5109                                 Exit Function
5110                             End If
5111                             ListTab.SelectedIndex = tabNo
5112                             ListTabSelect(ListTab.TabPages(tabNo))
5113                             Return Pressed
5114                         Case Keys.D9
5115                             ListTab.SelectedIndex = ListTab.TabPages.Count - 1
5116                             ListTabSelect(ListTab.TabPages(ListTab.TabPages.Count - 1))
5117                             Return Pressed
5118                         Case Else
5119                     End Select
5120                 ElseIf Focused = ModifierState.StatusText Then
5121                     If KeyCode = Keys.A Then
5122                         StatusText.SelectAll()
5123                         Return Pressed
5124                     ElseIf KeyCode = Keys.Up OrElse KeyCode = Keys.Down Then
5125                         If StatusText.Text.Trim() <> "" Then
5126                             _history(_hisIdx) = New PostingStatus(StatusText.Text, _reply_to_id, _reply_to_name)
5127                         End If
5128                         If KeyCode = Keys.Up Then
5129                             _hisIdx -= 1
5130                             If _hisIdx < 0 Then _hisIdx = 0
5131                         Else
5132                             _hisIdx += 1
5133                             If _hisIdx > _history.Count - 1 Then _hisIdx = _history.Count - 1
5134                         End If
5135                         StatusText.Text = _history(_hisIdx).status
5136                         _reply_to_id = _history(_hisIdx).inReplyToId
5137                         _reply_to_name = _history(_hisIdx).inReplyToName
5138                         StatusText.SelectionStart = StatusText.Text.Length
5139                         Pressed = True
5140                         Return Pressed
5141                     End If
5142                     If KeyCode = Keys.PageUp OrElse KeyCode = Keys.P Then
5143                         If ListTab.SelectedIndex = 0 Then
5144                             ListTab.SelectedIndex = ListTab.TabCount - 1
5145                         Else
5146                             ListTab.SelectedIndex -= 1
5147                         End If
5148                         Pressed = True
5149                         StatusText.Focus()
5150                     ElseIf KeyCode = Keys.PageDown OrElse KeyCode = Keys.N Then
5151                         If ListTab.SelectedIndex = ListTab.TabCount - 1 Then
5152                             ListTab.SelectedIndex = 0
5153                         Else
5154                             ListTab.SelectedIndex += 1
5155                         End If
5156                         Pressed = True
5157                         StatusText.Focus()
5158                     End If
5159                 Else
5160                     If KeyCode = Keys.A Then
5161                         Pressed = True
5162                         PostBrowser.Document.ExecCommand("SelectAll", False, Nothing)
5163                     ElseIf KeyCode = Keys.C OrElse KeyCode = Keys.Insert Then
5164                         Pressed = True
5165                         Dim _selText As String = WebBrowser_GetSelectionText(PostBrowser)
5166                         If Not String.IsNullOrEmpty(_selText) Then
5167                             Try
5168                                 Clipboard.SetDataObject(_selText, False, 5, 100)
5169                             Catch ex As Exception
5170                                 MessageBox.Show(ex.Message)
5171                             End Try
5172                         End If
5173                     ElseIf KeyCode = Keys.Y Then
5174                         Pressed = True
5175                         MultiLineMenuItem.Checked = Not MultiLineMenuItem.Checked
5176                         MultiLineMenuItem_Click(Nothing, Nothing)
5177                     End If
5178                 End If
5179
5180             End If
5181             Return Pressed
5182         End If
5183
5184         'SHift+何か
5185         If Modifier = ModifierState.Shift Then
5186             If KeyCode = Keys.F3 Then
5187                 Pressed = True
5188                 MenuItemSearchPrev_Click(Nothing, Nothing)
5189             ElseIf KeyCode = Keys.F5 Then
5190                 Pressed = True
5191                 DoRefreshMore()
5192             ElseIf KeyCode = Keys.F6 Then
5193                 Pressed = True
5194                 GetTimeline(WORKERTYPE.Reply, -1, 0, "")
5195             ElseIf KeyCode = Keys.F7 Then
5196                 Pressed = True
5197                 GetTimeline(WORKERTYPE.DirectMessegeRcv, -1, 0, "")
5198             End If
5199             If Focused <> ModifierState.StatusText Then
5200                 If KeyCode = Keys.R AndAlso Not Pressed Then
5201                     DoRefreshMore()
5202                     Return True
5203                 End If
5204                 If Focused = ModifierState.ListTab Then
5205                     If KeyCode = Keys.H Then
5206                         Pressed = True
5207                         GoTopEnd(True)
5208                     ElseIf KeyCode = Keys.L Then
5209                         Pressed = True
5210                         GoTopEnd(False)
5211                     ElseIf KeyCode = Keys.M Then
5212                         Pressed = True
5213                         GoMiddle()
5214                     ElseIf KeyCode = Keys.G Then
5215                         Pressed = True
5216                         GoLast()
5217                     ElseIf KeyCode = Keys.Z Then
5218                         Pressed = True
5219                         MoveMiddle()
5220                     ElseIf KeyCode = Keys.J Then
5221                         Pressed = True
5222                         SendKeys.Send("{DOWN}")
5223                     ElseIf KeyCode = Keys.K Then
5224                         Pressed = True
5225                         SendKeys.Send("{UP}")
5226                     ElseIf KeyCode = Keys.Oem4 Then
5227                         Pressed = True
5228                         GoBackInReplyToPostTree(True, False)
5229                     ElseIf KeyCode = Keys.Oem6 Then
5230                         Pressed = True
5231                         GoBackInReplyToPostTree(True, True)
5232                     End If
5233
5234                     ' お気に入り前後ジャンプ(SHIFT+N←/P→)
5235                     If KeyCode = Keys.N OrElse KeyCode = Keys.Right Then
5236                         Pressed = True
5237                         GoFav(True)
5238                     ElseIf KeyCode = Keys.P OrElse KeyCode = Keys.Left Then
5239                         Pressed = True
5240                         GoFav(False)
5241                     End If
5242                 End If
5243             End If
5244             Return Pressed
5245         End If
5246
5247         'Alt+何か
5248         If Modifier = ModifierState.Alt Then
5249             If KeyCode = Keys.R Then
5250                 Pressed = True
5251                 doReTweetOfficial(True)
5252             ElseIf KeyCode = Keys.P AndAlso _curPost IsNot Nothing Then
5253                 Pressed = True
5254                 doShowUserStatus(_curPost.ScreenName, False)
5255             End If
5256             If KeyCode = Keys.Up Then
5257                 ScrollDownPostBrowser(False)
5258             ElseIf KeyCode = Keys.Down Then
5259                 ScrollDownPostBrowser(True)
5260             ElseIf KeyCode = Keys.PageUp Then
5261                 PageDownPostBrowser(False)
5262             ElseIf KeyCode = Keys.PageDown Then
5263                 PageDownPostBrowser(True)
5264             End If
5265             If Focused = ModifierState.ListTab AndAlso Not Pressed Then
5266                 ' 別タブの同じ書き込みへ(ALT+←/→)
5267                 If KeyCode = Keys.Right Then
5268                     Pressed = True
5269                     GoSamePostToAnotherTab(False)
5270                 ElseIf KeyCode = Keys.Left Then
5271                     Pressed = True
5272                     GoSamePostToAnotherTab(True)
5273                 End If
5274             End If
5275             Return Pressed
5276         End If
5277
5278         'Ctrl+Shift+何か
5279         If Modifier = ModifierState.CShift Then
5280             If KeyCode = Keys.R Then
5281                 Pressed = True
5282                 MakeReplyOrDirectStatus(False, True, True)
5283             ElseIf KeyCode = Keys.C Then
5284                 Dim clstr As String = ""
5285                 Pressed = True
5286                 CopyIdUri()
5287             ElseIf KeyCode = Keys.F Then
5288                 Pressed = True
5289                 If ListTab.SelectedTab IsNot Nothing Then
5290                     If _statuses.Tabs(ListTab.SelectedTab.Text).TabType <> TabUsageType.PublicSearch Then Return Pressed
5291                     ListTab.SelectedTab.Controls("panelSearch").Controls("comboSearch").Focus()
5292                 End If
5293             ElseIf KeyCode = Keys.S Then
5294                 Pressed = True
5295                 FavoriteChange(False)
5296             ElseIf KeyCode = Keys.B Then
5297                 Pressed = True
5298                 UnreadStripMenuItem_Click(Nothing, Nothing)
5299             End If
5300             If KeyCode = Keys.T Then
5301                 Pressed = True
5302                 HashToggleMenuItem_Click(Nothing, Nothing)
5303             ElseIf KeyCode = Keys.P Then
5304                 Pressed = True
5305                 ImageSelectMenuItem_Click(Nothing, Nothing)
5306             ElseIf KeyCode = Keys.H Then
5307                 Pressed = True
5308                 doMoveToRTHome()
5309             ElseIf KeyCode = Keys.O Then
5310                 Pressed = True
5311                 FavorareMenuItem_Click(Nothing, Nothing)
5312             End If
5313             If Not Pressed AndAlso Focused = ModifierState.StatusText Then
5314                 If KeyCode = Keys.Up Then
5315                     Pressed = True
5316                     Dim idx As Integer = 0
5317                     If _curList IsNot Nothing AndAlso _curList.Items.Count <> 0 AndAlso _
5318                                 _curList.SelectedIndices.Count > 0 AndAlso _curList.SelectedIndices(0) > 0 Then
5319                         idx = _curList.SelectedIndices(0) - 1
5320                         SelectListItem(_curList, idx)
5321                         _curList.EnsureVisible(idx)
5322                     End If
5323                 ElseIf KeyCode = Keys.Down Then
5324                     Pressed = True
5325                     Dim idx As Integer = 0
5326                     If _curList IsNot Nothing AndAlso _curList.Items.Count <> 0 AndAlso _curList.SelectedIndices.Count > 0 _
5327                                 AndAlso _curList.SelectedIndices(0) < _curList.Items.Count - 1 Then
5328                         idx = _curList.SelectedIndices(0) + 1
5329                         SelectListItem(_curList, idx)
5330                         _curList.EnsureVisible(idx)
5331                     End If
5332                 ElseIf KeyCode = Keys.Space Then
5333                     If StatusText.SelectionStart > 0 Then
5334                         Dim endidx As Integer = StatusText.SelectionStart - 1
5335                         Dim startstr As String = ""
5336                         For i As Integer = StatusText.SelectionStart - 1 To 0 Step -1
5337                             Dim c As Char = StatusText.Text.Chars(i)
5338                             If Char.IsLetterOrDigit(c) OrElse c = "_" Then
5339                                 Continue For
5340                             End If
5341                             If c = "@" Then
5342                                 Pressed = True
5343                                 startstr = StatusText.Text.Substring(i + 1, endidx - i)
5344                                 ShowSuplDialog(StatusText, AtIdSupl, startstr.Length + 1, startstr)
5345                             ElseIf c = "#" Then
5346                                 Pressed = True
5347                                 startstr = StatusText.Text.Substring(i + 1, endidx - i)
5348                                 ShowSuplDialog(StatusText, HashSupl, startstr.Length + 1, startstr)
5349                             Else
5350                                 Exit For
5351                             End If
5352                         Next
5353                         Return Pressed
5354                     End If
5355                 End If
5356             End If
5357             Return Pressed
5358         End If
5359
5360         'Ctrl+Alt+何か
5361         If Modifier = ModifierState.CAlt Then
5362             If KeyCode = Keys.S Then
5363                 Pressed = True
5364                 FavoritesRetweetOriginal()
5365             ElseIf KeyCode = Keys.R Then
5366                 Pressed = True
5367                 FavoritesRetweetUnofficial()
5368             End If
5369             Return Pressed
5370         End If
5371
5372         'Alt+Shift+何か
5373         If Modifier = ModifierState.AShift Then
5374             If Focused = ModifierState.PostBrowser Then
5375                 If KeyCode = Keys.R Then
5376                     doReTweetUnofficial()
5377                 ElseIf KeyCode = Keys.C Then
5378                     CopyUserId()
5379                 End If
5380                 Return Pressed
5381             Else
5382                 If KeyCode = Keys.R Then
5383                     Pressed = True
5384                     doReTweetUnofficial()
5385                 ElseIf KeyCode = Keys.C Then
5386                     Pressed = True
5387                     CopyUserId()
5388                 ElseIf KeyCode = Keys.Up Then
5389                     Thumbnail.ScrollThumbnail(False)
5390                 ElseIf KeyCode = Keys.Down Then
5391                     Thumbnail.ScrollThumbnail(True)
5392                 End If
5393                 If Focused = ModifierState.ListTab AndAlso KeyCode = Keys.Enter Then
5394                     If Not Me.SplitContainer3.Panel2Collapsed Then
5395                         Thumbnail.OpenPicture()
5396                     End If
5397                     Pressed = True
5398                 End If
5399                 Return Pressed
5400             End If
5401         End If
5402         Return Pressed
5403     End Function
5404
5405     Private Sub ScrollDownPostBrowser(ByVal forward As Boolean)
5406         Dim doc As HtmlDocument = PostBrowser.Document
5407         If doc Is Nothing Then Exit Sub
5408         If doc.Body Is Nothing Then Exit Sub
5409
5410         If forward Then
5411             doc.Body.ScrollTop += SettingDialog.FontDetail.Height
5412         Else
5413             doc.Body.ScrollTop -= SettingDialog.FontDetail.Height
5414         End If
5415     End Sub
5416
5417     Private Sub PageDownPostBrowser(ByVal forward As Boolean)
5418         Dim doc As HtmlDocument = PostBrowser.Document
5419         If doc Is Nothing Then Exit Sub
5420         If doc.Body Is Nothing Then Exit Sub
5421
5422         If forward Then
5423             doc.Body.ScrollTop += PostBrowser.ClientRectangle.Height - SettingDialog.FontDetail.Height
5424         Else
5425             doc.Body.ScrollTop -= PostBrowser.ClientRectangle.Height - SettingDialog.FontDetail.Height
5426         End If
5427     End Sub
5428
5429     Private Sub GoNextTab(ByVal forward As Boolean)
5430         Dim idx As Integer = ListTab.SelectedIndex
5431         If forward Then
5432             idx += 1
5433             If idx > ListTab.TabPages.Count - 1 Then idx = 0
5434         Else
5435             idx -= 1
5436             If idx < 0 Then idx = ListTab.TabPages.Count - 1
5437         End If
5438         ListTab.SelectedIndex = idx
5439         ListTabSelect(ListTab.TabPages(idx))
5440     End Sub
5441
5442     Private Sub CopyStot()
5443         Dim clstr As String = ""
5444         Dim sb As New StringBuilder()
5445         Dim IsProtected As Boolean = False
5446         Dim isDm As Boolean = False
5447         If Me._curTab IsNot Nothing AndAlso Me._statuses.GetTabByName(Me._curTab.Text) IsNot Nothing Then isDm = Me._statuses.GetTabByName(Me._curTab.Text).TabType = TabUsageType.DirectMessage
5448         For Each idx As Integer In _curList.SelectedIndices
5449             Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
5450             If post.IsProtect Then
5451                 IsProtected = True
5452                 Continue For
5453             End If
5454             If post.IsDeleted Then Continue For
5455             If Not isDm Then
5456                 If post.RetweetedId > 0 Then
5457                     sb.AppendFormat("{0}:{1} [http://twitter.com/{0}/status/{2}]{3}", post.ScreenName, post.TextFromApi, post.RetweetedId, Environment.NewLine)
5458                 Else
5459                     sb.AppendFormat("{0}:{1} [http://twitter.com/{0}/status/{2}]{3}", post.ScreenName, post.TextFromApi, post.StatusId, Environment.NewLine)
5460                 End If
5461             Else
5462                 sb.AppendFormat("{0}:{1} [{2}]{3}", post.ScreenName, post.TextFromApi, post.StatusId, Environment.NewLine)
5463             End If
5464         Next
5465         If IsProtected Then
5466             MessageBox.Show(My.Resources.CopyStotText1)
5467         End If
5468         If sb.Length > 0 Then
5469             clstr = sb.ToString()
5470             Try
5471                 Clipboard.SetDataObject(clstr, False, 5, 100)
5472             Catch ex As Exception
5473                 MessageBox.Show(ex.Message)
5474             End Try
5475         End If
5476     End Sub
5477
5478     Private Sub CopyIdUri()
5479         Dim clstr As String = ""
5480         Dim sb As New StringBuilder()
5481         If Me._curTab Is Nothing Then Exit Sub
5482         If Me._statuses.GetTabByName(Me._curTab.Text) Is Nothing Then Exit Sub
5483         If Me._statuses.GetTabByName(Me._curTab.Text).TabType = TabUsageType.DirectMessage Then Exit Sub
5484         For Each idx As Integer In _curList.SelectedIndices
5485             Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
5486             If post.RetweetedId > 0 Then
5487                 sb.AppendFormat("http://twitter.com/{0}/status/{1}{2}", post.ScreenName, post.RetweetedId, Environment.NewLine)
5488             Else
5489                 sb.AppendFormat("http://twitter.com/{0}/status/{1}{2}", post.ScreenName, post.StatusId, Environment.NewLine)
5490             End If
5491         Next
5492         If sb.Length > 0 Then
5493             clstr = sb.ToString()
5494             Try
5495                 Clipboard.SetDataObject(clstr, False, 5, 100)
5496             Catch ex As Exception
5497                 MessageBox.Show(ex.Message)
5498             End Try
5499         End If
5500     End Sub
5501
5502     Private Sub GoFav(ByVal forward As Boolean)
5503         If _curList.VirtualListSize = 0 Then Exit Sub
5504         Dim fIdx As Integer = 0
5505         Dim toIdx As Integer = 0
5506         Dim stp As Integer = 1
5507
5508         If forward Then
5509             If _curList.SelectedIndices.Count = 0 Then
5510                 fIdx = 0
5511             Else
5512                 fIdx = _curList.SelectedIndices(0) + 1
5513                 If fIdx > _curList.VirtualListSize - 1 Then Exit Sub
5514             End If
5515             toIdx = _curList.VirtualListSize - 1
5516             stp = 1
5517         Else
5518             If _curList.SelectedIndices.Count = 0 Then
5519                 fIdx = _curList.VirtualListSize - 1
5520             Else
5521                 fIdx = _curList.SelectedIndices(0) - 1
5522                 If fIdx < 0 Then Exit Sub
5523             End If
5524             toIdx = 0
5525             stp = -1
5526         End If
5527
5528         For idx As Integer = fIdx To toIdx Step stp
5529             If _statuses.Item(_curTab.Text, idx).IsFav Then
5530                 SelectListItem(_curList, idx)
5531                 _curList.EnsureVisible(idx)
5532                 Exit For
5533             End If
5534         Next
5535     End Sub
5536
5537     Private Sub GoSamePostToAnotherTab(ByVal left As Boolean)
5538         If _curList.VirtualListSize = 0 Then Exit Sub
5539         Dim fIdx As Integer = 0
5540         Dim toIdx As Integer = 0
5541         Dim stp As Integer = 1
5542         Dim targetId As Long = 0
5543
5544         If _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage Then Exit Sub ' Directタブは対象外(見つかるはずがない)
5545         If _curList.SelectedIndices.Count = 0 Then Exit Sub '未選択も処理しない
5546
5547         targetId = GetCurTabPost(_curList.SelectedIndices(0)).StatusId
5548
5549         If left Then
5550             ' 左のタブへ
5551             If ListTab.SelectedIndex = 0 Then
5552                 Exit Sub
5553             Else
5554                 fIdx = ListTab.SelectedIndex - 1
5555             End If
5556             toIdx = 0
5557             stp = -1
5558         Else
5559             ' 右のタブへ
5560             If ListTab.SelectedIndex = ListTab.TabCount - 1 Then
5561                 Exit Sub
5562             Else
5563                 fIdx = ListTab.SelectedIndex + 1
5564             End If
5565             toIdx = ListTab.TabCount - 1
5566             stp = 1
5567         End If
5568
5569         Dim found As Boolean = False
5570         For tabidx As Integer = fIdx To toIdx Step stp
5571             If _statuses.Tabs(ListTab.TabPages(tabidx).Text).TabType = TabUsageType.DirectMessage Then Continue For ' Directタブは対象外
5572             For idx As Integer = 0 To DirectCast(ListTab.TabPages(tabidx).Tag, DetailsListView).VirtualListSize - 1
5573                 If _statuses.Item(ListTab.TabPages(tabidx).Text, idx).StatusId = targetId Then
5574                     ListTab.SelectedIndex = tabidx
5575                     ListTabSelect(ListTab.TabPages(tabidx))
5576                     SelectListItem(_curList, idx)
5577                     _curList.EnsureVisible(idx)
5578                     found = True
5579                     Exit For
5580                 End If
5581             Next
5582             If found Then Exit For
5583         Next
5584     End Sub
5585
5586     Private Sub GoPost(ByVal forward As Boolean)
5587         If _curList.SelectedIndices.Count = 0 OrElse _curPost Is Nothing Then Exit Sub
5588         Dim fIdx As Integer = 0
5589         Dim toIdx As Integer = 0
5590         Dim stp As Integer = 1
5591
5592         If forward Then
5593             fIdx = _curList.SelectedIndices(0) + 1
5594             If fIdx > _curList.VirtualListSize - 1 Then Exit Sub
5595             toIdx = _curList.VirtualListSize - 1
5596             stp = 1
5597         Else
5598             fIdx = _curList.SelectedIndices(0) - 1
5599             If fIdx < 0 Then Exit Sub
5600             toIdx = 0
5601             stp = -1
5602         End If
5603
5604         Dim name As String = ""
5605         If _curPost.RetweetedId = 0 Then
5606             name = _curPost.ScreenName
5607         Else
5608             name = _curPost.RetweetedBy
5609         End If
5610         For idx As Integer = fIdx To toIdx Step stp
5611             If _statuses.Item(_curTab.Text, idx).RetweetedId = 0 Then
5612                 If _statuses.Item(_curTab.Text, idx).ScreenName = name Then
5613                     SelectListItem(_curList, idx)
5614                     _curList.EnsureVisible(idx)
5615                     Exit For
5616                 End If
5617             Else
5618                 If _statuses.Item(_curTab.Text, idx).RetweetedBy = name Then
5619                     SelectListItem(_curList, idx)
5620                     _curList.EnsureVisible(idx)
5621                     Exit For
5622                 End If
5623             End If
5624         Next
5625     End Sub
5626
5627     Private Sub GoRelPost(ByVal forward As Boolean)
5628         If _curList.SelectedIndices.Count = 0 Then Exit Sub
5629
5630         Dim fIdx As Integer = 0
5631         Dim toIdx As Integer = 0
5632         Dim stp As Integer = 1
5633         If forward Then
5634             fIdx = _curList.SelectedIndices(0) + 1
5635             If fIdx > _curList.VirtualListSize - 1 Then Exit Sub
5636             toIdx = _curList.VirtualListSize - 1
5637             stp = 1
5638         Else
5639             fIdx = _curList.SelectedIndices(0) - 1
5640             If fIdx < 0 Then Exit Sub
5641             toIdx = 0
5642             stp = -1
5643         End If
5644
5645         If Not _anchorFlag Then
5646             If _curPost Is Nothing Then Exit Sub
5647             _anchorPost = _curPost
5648             _anchorFlag = True
5649         Else
5650             If _anchorPost Is Nothing Then Exit Sub
5651         End If
5652
5653         For idx As Integer = fIdx To toIdx Step stp
5654             Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
5655             If post.ScreenName = _anchorPost.ScreenName OrElse _
5656                post.RetweetedBy = _anchorPost.ScreenName OrElse _
5657                post.ScreenName = _anchorPost.RetweetedBy OrElse _
5658                (Not String.IsNullOrEmpty(post.RetweetedBy) AndAlso post.RetweetedBy = _anchorPost.RetweetedBy) OrElse _
5659                _anchorPost.ReplyToList.Contains(post.ScreenName.ToLower()) OrElse _
5660                _anchorPost.ReplyToList.Contains(post.RetweetedBy.ToLower()) OrElse _
5661                post.ReplyToList.Contains(_anchorPost.ScreenName.ToLower()) OrElse _
5662                post.ReplyToList.Contains(_anchorPost.RetweetedBy.ToLower()) Then
5663                 SelectListItem(_curList, idx)
5664                 _curList.EnsureVisible(idx)
5665                 Exit For
5666             End If
5667         Next
5668     End Sub
5669
5670     Private Sub GoAnchor()
5671         If _anchorPost Is Nothing Then Exit Sub
5672         Dim idx As Integer = _statuses.Tabs(_curTab.Text).IndexOf(_anchorPost.StatusId)
5673         If idx = -1 Then Exit Sub
5674
5675         SelectListItem(_curList, idx)
5676         _curList.EnsureVisible(idx)
5677     End Sub
5678
5679     Private Sub GoTopEnd(ByVal GoTop As Boolean)
5680         Dim _item As ListViewItem
5681         Dim idx As Integer
5682
5683         If GoTop Then
5684             _item = _curList.GetItemAt(0, 25)
5685             If _item Is Nothing Then
5686                 idx = 0
5687             Else
5688                 idx = _item.Index
5689             End If
5690         Else
5691             _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1)
5692             If _item Is Nothing Then
5693                 idx = _curList.VirtualListSize - 1
5694             Else
5695                 idx = _item.Index
5696             End If
5697         End If
5698         SelectListItem(_curList, idx)
5699     End Sub
5700
5701     Private Sub GoMiddle()
5702         Dim _item As ListViewItem
5703         Dim idx1 As Integer
5704         Dim idx2 As Integer
5705         Dim idx3 As Integer
5706
5707         _item = _curList.GetItemAt(0, 0)
5708         If _item Is Nothing Then
5709             idx1 = 0
5710         Else
5711             idx1 = _item.Index
5712         End If
5713         _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1)
5714         If _item Is Nothing Then
5715             idx2 = _curList.VirtualListSize - 1
5716         Else
5717             idx2 = _item.Index
5718         End If
5719         idx3 = (idx1 + idx2) \ 2
5720
5721         SelectListItem(_curList, idx3)
5722     End Sub
5723
5724     Private Sub GoLast()
5725         If _curList.VirtualListSize = 0 Then Exit Sub
5726
5727         If _statuses.SortOrder = SortOrder.Ascending Then
5728             SelectListItem(_curList, _curList.VirtualListSize - 1)
5729             _curList.EnsureVisible(_curList.VirtualListSize - 1)
5730         Else
5731             SelectListItem(_curList, 0)
5732             _curList.EnsureVisible(0)
5733         End If
5734     End Sub
5735
5736     Private Sub MoveTop()
5737         If _curList.SelectedIndices.Count = 0 Then Exit Sub
5738         Dim idx As Integer = _curList.SelectedIndices(0)
5739         If _statuses.SortOrder = SortOrder.Ascending Then
5740             _curList.EnsureVisible(_curList.VirtualListSize - 1)
5741         Else
5742             _curList.EnsureVisible(0)
5743         End If
5744         _curList.EnsureVisible(idx)
5745     End Sub
5746
5747     Private Sub GoInReplyToPostTree()
5748         If _curPost Is Nothing Then Return
5749
5750         Dim curTabClass As TabClass = _statuses.Tabs(_curTab.Text)
5751
5752         If curTabClass.TabType = TabUsageType.PublicSearch AndAlso _curPost.InReplyToStatusId = 0 AndAlso _curPost.TextFromApi.Contains("@") Then
5753             Dim post As PostClass = Nothing
5754             Dim r As String = tw.GetStatusApi(False, _curPost.StatusId, post)
5755             If r = "" AndAlso post IsNot Nothing Then
5756                 _curPost.InReplyToStatusId = post.InReplyToStatusId
5757                 _curPost.InReplyToUser = post.InReplyToUser
5758                 _curPost.IsReply = post.IsReply
5759                 _itemCache = Nothing
5760                 _curList.RedrawItems(_curItemIndex, _curItemIndex, False)
5761             Else
5762                 Me.StatusLabel.Text = r
5763             End If
5764         End If
5765
5766         If Not (Me.ExistCurrentPost AndAlso _curPost.InReplyToUser IsNot Nothing AndAlso _curPost.InReplyToStatusId > 0) Then Return
5767
5768         If replyChains Is Nothing OrElse (replyChains.Count > 0 AndAlso replyChains.Peek().InReplyToId <> _curPost.StatusId) Then
5769             replyChains = New Stack(Of ReplyChain)
5770         End If
5771         replyChains.Push(New ReplyChain(_curPost.StatusId, _curPost.InReplyToStatusId, _curTab))
5772
5773         Dim inReplyToIndex As Integer
5774         Dim inReplyToTabName As String
5775         Dim inReplyToId As Long = _curPost.InReplyToStatusId
5776         Dim inReplyToUser As String = _curPost.InReplyToUser
5777         Dim curTabPosts As Dictionary(Of Long, PostClass)
5778
5779         If _statuses.Tabs(_curTab.Text).IsInnerStorageTabType Then
5780             curTabPosts = curTabClass.Posts
5781         Else
5782             curTabPosts = _statuses.Posts
5783         End If
5784
5785         Dim inReplyToPosts = From tab In _statuses.Tabs.Values
5786                              Order By tab IsNot curTabClass
5787                              From post In DirectCast(IIf(tab.IsInnerStorageTabType, tab.Posts, _statuses.Posts), Dictionary(Of Long, PostClass)).Values
5788                              Where post.StatusId = inReplyToId
5789                              Let index = tab.IndexOf(post.StatusId)
5790                              Where index <> -1
5791                              Select New With {.Tab = tab, .Index = index}
5792
5793         Try
5794             Dim inReplyPost = inReplyToPosts.First()
5795             inReplyToTabName = inReplyPost.Tab.TabName
5796             inReplyToIndex = inReplyPost.Index
5797         Catch ex As InvalidOperationException
5798             Dim post As PostClass = Nothing
5799             Dim r As String = tw.GetStatusApi(False, _curPost.InReplyToStatusId, post)
5800             If r = "" AndAlso post IsNot Nothing Then
5801                 post.IsRead = True
5802                 _statuses.AddPost(post)
5803                 _statuses.DistributePosts()
5804                 '_statuses.SubmitUpdate(Nothing, Nothing, Nothing, False)
5805                 Me.RefreshTimeline(False)
5806                 Try
5807                     Dim inReplyPost = inReplyToPosts.First()
5808                     inReplyToTabName = inReplyPost.Tab.TabName
5809                     inReplyToIndex = inReplyPost.Index
5810                 Catch ex2 As InvalidOperationException
5811                     OpenUriAsync("http://twitter.com/" + inReplyToUser + "/statuses/" + inReplyToId.ToString())
5812                     Exit Sub
5813                 End Try
5814             Else
5815                 Me.StatusLabel.Text = r
5816                 OpenUriAsync("http://twitter.com/" + inReplyToUser + "/statuses/" + inReplyToId.ToString())
5817                 Exit Sub
5818             End If
5819         End Try
5820
5821         Dim tabPage = Me.ListTab.TabPages.Cast(Of TabPage).First(Function(tp) tp.Text = inReplyToTabName)
5822         Dim listView = DirectCast(tabPage.Tag, DetailsListView)
5823
5824         If _curTab IsNot tabPage Then
5825             Me.ListTab.SelectTab(tabPage)
5826         End If
5827
5828         Me.SelectListItem(listView, inReplyToIndex)
5829         listView.EnsureVisible(inReplyToIndex)
5830     End Sub
5831
5832     Private Sub GoBackInReplyToPostTree(Optional ByVal parallel As Boolean = False, Optional ByVal isForward As Boolean = True)
5833         If _curPost Is Nothing Then Return
5834
5835         Dim curTabClass As TabClass = _statuses.Tabs(_curTab.Text)
5836         Dim curTabPosts As Dictionary(Of Long, PostClass) = DirectCast(IIf(curTabClass.IsInnerStorageTabType, curTabClass.Posts, _statuses.Posts), Dictionary(Of Long, PostClass))
5837
5838         If parallel Then
5839             If _curPost.InReplyToStatusId <> 0 Then
5840                 Dim posts = From t In _statuses.Tabs
5841                             From p In DirectCast(IIf(t.Value.IsInnerStorageTabType, t.Value.Posts, _statuses.Posts), Dictionary(Of Long, PostClass))
5842                             Where p.Value.StatusId <> _curPost.StatusId AndAlso p.Value.InReplyToStatusId = _curPost.InReplyToStatusId
5843                             Let indexOf = t.Value.IndexOf(p.Value.StatusId)
5844                             Where indexOf > -1
5845                             Order By IIf(isForward, indexOf, indexOf * -1)
5846                             Order By t.Value IsNot curTabClass
5847                             Select New With {.Tab = t.Value, .Post = p.Value, .Index = indexOf}
5848                 Try
5849                     Dim postList = posts.ToList()
5850                     For i As Integer = postList.Count - 1 To 0 Step -1
5851                         Dim index As Integer = i
5852                         If postList.FindIndex(Function(pst) pst.Post.StatusId = postList(index).Post.StatusId) <> index Then
5853                             postList.RemoveAt(index)
5854                         End If
5855                     Next
5856                     Dim post = postList.FirstOrDefault(Function(pst) pst.Tab Is curTabClass AndAlso DirectCast(IIf(isForward, pst.Index > _curItemIndex, pst.Index < _curItemIndex), Boolean))
5857                     If post Is Nothing Then post = postList.FirstOrDefault(Function(pst) pst.Tab IsNot curTabClass)
5858                     If post Is Nothing Then post = postList.First()
5859                     Me.ListTab.SelectTab(Me.ListTab.TabPages.Cast(Of TabPage).First(Function(tp) tp.Text = post.Tab.TabName))
5860                     Dim listView = DirectCast(Me.ListTab.SelectedTab.Tag, DetailsListView)
5861                     SelectListItem(listView, post.Index)
5862                     listView.EnsureVisible(post.Index)
5863                 Catch ex As InvalidOperationException
5864                     Exit Sub
5865                 End Try
5866             End If
5867         Else
5868             If replyChains Is Nothing OrElse replyChains.Count < 1 Then
5869                 Dim posts = From t In _statuses.Tabs
5870                             From p In DirectCast(IIf(t.Value.IsInnerStorageTabType, t.Value.Posts, _statuses.Posts), Dictionary(Of Long, PostClass))
5871                             Where p.Value.InReplyToStatusId = _curPost.StatusId
5872                             Let indexOf = t.Value.IndexOf(p.Value.StatusId)
5873                             Where indexOf > -1
5874                             Order By indexOf
5875                             Order By t.Value IsNot curTabClass
5876                             Select New With {.Tab = t.Value, .Index = indexOf}
5877                 Try
5878                     Dim post = posts.First()
5879                     Me.ListTab.SelectTab(Me.ListTab.TabPages.Cast(Of TabPage).First(Function(tp) tp.Text = post.Tab.TabName))
5880                     Dim listView = DirectCast(Me.ListTab.SelectedTab.Tag, DetailsListView)
5881                     SelectListItem(listView, post.Index)
5882                     listView.EnsureVisible(post.Index)
5883                 Catch ex As InvalidOperationException
5884                     Exit Sub
5885                 End Try
5886             Else
5887                 Dim chainHead As ReplyChain = replyChains.Pop()
5888                 If chainHead.InReplyToId = _curPost.StatusId Then
5889                     Dim idx As Integer = _statuses.Tabs(chainHead.OriginalTab.Text).IndexOf(chainHead.OriginalId)
5890                     If idx = -1 Then
5891                         replyChains = Nothing
5892                     Else
5893                         Try
5894                             ListTab.SelectTab(chainHead.OriginalTab)
5895                         Catch ex As Exception
5896                             replyChains = Nothing
5897                         End Try
5898                         SelectListItem(_curList, idx)
5899                         _curList.EnsureVisible(idx)
5900                     End If
5901                 Else
5902                     replyChains = Nothing
5903                     Me.GoBackInReplyToPostTree(parallel)
5904                 End If
5905             End If
5906         End If
5907     End Sub
5908
5909     Private Sub MyList_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
5910         _anchorFlag = False
5911     End Sub
5912
5913     Private Sub StatusText_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusText.Enter
5914         ' フォーカスの戻り先を StatusText に設定
5915         Me.Tag = StatusText
5916         StatusText.BackColor = _clInputBackcolor
5917     End Sub
5918
5919     Public Property InputBackColor() As System.Drawing.Color
5920         Get
5921             Return _clInputBackcolor
5922         End Get
5923         Set(ByVal value As System.Drawing.Color)
5924             _clInputBackcolor = value
5925         End Set
5926     End Property
5927
5928     Private Sub StatusText_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusText.Leave
5929         ' フォーカスがメニューに遷移しないならばフォーカスはタブに移ることを期待
5930         If ListTab.SelectedTab IsNot Nothing AndAlso MenuStrip1.Tag Is Nothing Then Me.Tag = ListTab.SelectedTab.Tag
5931         StatusText.BackColor = Color.FromKnownColor(KnownColor.Window)
5932     End Sub
5933
5934     Private Sub StatusText_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles StatusText.KeyDown
5935         Dim State As ModifierState = GetModifierState(e.Control, e.Shift, e.Alt)
5936         If State = ModifierState.NotFlags Then Exit Sub
5937         If CommonKeyDown(e.KeyCode, ModifierState.StatusText, State) Then
5938             e.Handled = True
5939             e.SuppressKeyPress = True
5940         End If
5941
5942         Me.StatusText_TextChanged(Nothing, Nothing)
5943     End Sub
5944
5945     Private Sub SaveConfigsAll(ByVal ifModified As Boolean)
5946         If Not ifModified Then
5947             SaveConfigsCommon()
5948             SaveConfigsLocal()
5949             'SaveConfigsTab(True)    'True:事前に設定ファイル削除
5950             SaveConfigsTabs()
5951         Else
5952             If _modifySettingCommon Then SaveConfigsCommon()
5953             If _modifySettingLocal Then SaveConfigsLocal()
5954             If _modifySettingAtId AndAlso SettingDialog.UseAtIdSupplement AndAlso AtIdSupl IsNot Nothing Then
5955                 _modifySettingAtId = False
5956                 Dim cfgAtId As New SettingAtIdList(AtIdSupl.GetItemList)
5957                 cfgAtId.Save()
5958             End If
5959         End If
5960     End Sub
5961
5962     Private Sub SaveConfigsCommon()
5963         If _ignoreConfigSave Then Exit Sub
5964
5965         _modifySettingCommon = False
5966         SyncLock _syncObject
5967             _cfgCommon.UserName = tw.Username
5968             _cfgCommon.Password = tw.Password
5969             _cfgCommon.IsOAuth = SettingDialog.IsOAuth
5970             _cfgCommon.Token = tw.AccessToken
5971             _cfgCommon.TokenSecret = tw.AccessTokenSecret
5972             _cfgCommon.UserstreamStartup = SettingDialog.UserstreamStartup
5973             _cfgCommon.UserstreamPeriod = SettingDialog.UserstreamPeriodInt
5974             _cfgCommon.TimelinePeriod = SettingDialog.TimelinePeriodInt
5975             _cfgCommon.ReplyPeriod = SettingDialog.ReplyPeriodInt
5976             _cfgCommon.DMPeriod = SettingDialog.DMPeriodInt
5977             _cfgCommon.PubSearchPeriod = SettingDialog.PubSearchPeriodInt
5978             _cfgCommon.ListsPeriod = SettingDialog.ListsPeriodInt
5979             _cfgCommon.UserTimelinePeriod = SettingDialog.UserTimelinePeriodInt
5980             _cfgCommon.Read = SettingDialog.Readed
5981             _cfgCommon.IconSize = SettingDialog.IconSz
5982             _cfgCommon.UnreadManage = SettingDialog.UnreadManage
5983             _cfgCommon.PlaySound = SettingDialog.PlaySound
5984             _cfgCommon.OneWayLove = SettingDialog.OneWayLove
5985
5986             _cfgCommon.NameBalloon = SettingDialog.NameBalloon
5987             _cfgCommon.PostCtrlEnter = SettingDialog.PostCtrlEnter
5988             _cfgCommon.PostShiftEnter = SettingDialog.PostShiftEnter
5989             _cfgCommon.CountApi = SettingDialog.CountApi
5990             _cfgCommon.CountApiReply = SettingDialog.CountApiReply
5991             _cfgCommon.PostAndGet = SettingDialog.PostAndGet
5992             _cfgCommon.DispUsername = SettingDialog.DispUsername
5993             _cfgCommon.MinimizeToTray = SettingDialog.MinimizeToTray
5994             _cfgCommon.CloseToExit = SettingDialog.CloseToExit
5995             _cfgCommon.DispLatestPost = SettingDialog.DispLatestPost
5996             _cfgCommon.SortOrderLock = SettingDialog.SortOrderLock
5997             _cfgCommon.TinyUrlResolve = SettingDialog.TinyUrlResolve
5998             _cfgCommon.PeriodAdjust = SettingDialog.PeriodAdjust
5999             _cfgCommon.StartupVersion = SettingDialog.StartupVersion
6000             _cfgCommon.StartupFollowers = SettingDialog.StartupFollowers
6001             _cfgCommon.RestrictFavCheck = SettingDialog.RestrictFavCheck
6002             _cfgCommon.AlwaysTop = SettingDialog.AlwaysTop
6003             _cfgCommon.UrlConvertAuto = SettingDialog.UrlConvertAuto
6004             _cfgCommon.Outputz = SettingDialog.OutputzEnabled
6005             _cfgCommon.OutputzKey = SettingDialog.OutputzKey
6006             _cfgCommon.OutputzUrlMode = SettingDialog.OutputzUrlmode
6007             _cfgCommon.UseUnreadStyle = SettingDialog.UseUnreadStyle
6008             _cfgCommon.DateTimeFormat = SettingDialog.DateTimeFormat
6009             _cfgCommon.DefaultTimeOut = SettingDialog.DefaultTimeOut
6010             _cfgCommon.RetweetNoConfirm = SettingDialog.RetweetNoConfirm
6011             _cfgCommon.LimitBalloon = SettingDialog.LimitBalloon
6012             _cfgCommon.EventNotifyEnabled = SettingDialog.EventNotifyEnabled
6013             _cfgCommon.EventNotifyFlag = SettingDialog.EventNotifyFlag
6014             _cfgCommon.IsMyEventNotifyFlag = SettingDialog.IsMyEventNotifyFlag
6015             _cfgCommon.ForceEventNotify = SettingDialog.ForceEventNotify
6016             _cfgCommon.FavEventUnread = SettingDialog.FavEventUnread
6017             _cfgCommon.TranslateLanguage = SettingDialog.TranslateLanguage
6018             _cfgCommon.EventSoundFile = SettingDialog.EventSoundFile
6019             _cfgCommon.AutoShortUrlFirst = SettingDialog.AutoShortUrlFirst
6020             _cfgCommon.TabIconDisp = SettingDialog.TabIconDisp
6021             _cfgCommon.ReplyIconState = SettingDialog.ReplyIconState
6022             _cfgCommon.ReadOwnPost = SettingDialog.ReadOwnPost
6023             _cfgCommon.GetFav = SettingDialog.GetFav
6024             _cfgCommon.IsMonospace = SettingDialog.IsMonospace
6025             If IdeographicSpaceToSpaceToolStripMenuItem IsNot Nothing AndAlso _
6026                IdeographicSpaceToSpaceToolStripMenuItem.IsDisposed = False Then
6027                 _cfgCommon.WideSpaceConvert = Me.IdeographicSpaceToSpaceToolStripMenuItem.Checked
6028             End If
6029             _cfgCommon.ReadOldPosts = SettingDialog.ReadOldPosts
6030             _cfgCommon.UseSsl = SettingDialog.UseSsl
6031             _cfgCommon.BilyUser = SettingDialog.BitlyUser
6032             _cfgCommon.BitlyPwd = SettingDialog.BitlyPwd
6033             _cfgCommon.ShowGrid = SettingDialog.ShowGrid
6034             _cfgCommon.UseAtIdSupplement = SettingDialog.UseAtIdSupplement
6035             _cfgCommon.UseHashSupplement = SettingDialog.UseHashSupplement
6036             _cfgCommon.PreviewEnable = SettingDialog.PreviewEnable
6037             _cfgCommon.Language = SettingDialog.Language
6038
6039             _cfgCommon.SortOrder = _statuses.SortOrder
6040             Select Case _statuses.SortMode
6041                 Case IdComparerClass.ComparerMode.Nickname  'ニックネーム
6042                     _cfgCommon.SortColumn = 1
6043                 Case IdComparerClass.ComparerMode.Data  '本文
6044                     _cfgCommon.SortColumn = 2
6045                 Case IdComparerClass.ComparerMode.Id  '時刻=発言Id
6046                     _cfgCommon.SortColumn = 3
6047                 Case IdComparerClass.ComparerMode.Name  '名前
6048                     _cfgCommon.SortColumn = 4
6049                 Case IdComparerClass.ComparerMode.Source  'Source
6050                     _cfgCommon.SortColumn = 7
6051             End Select
6052
6053             _cfgCommon.Nicoms = SettingDialog.Nicoms
6054             _cfgCommon.HashTags = HashMgr.HashHistories
6055             If HashMgr.IsPermanent Then
6056                 _cfgCommon.HashSelected = HashMgr.UseHash
6057             Else
6058                 _cfgCommon.HashSelected = ""
6059             End If
6060             _cfgCommon.HashIsHead = HashMgr.IsHead
6061             _cfgCommon.HashIsPermanent = HashMgr.IsPermanent
6062             _cfgCommon.TwitterUrl = SettingDialog.TwitterApiUrl
6063             _cfgCommon.TwitterSearchUrl = SettingDialog.TwitterSearchApiUrl
6064             _cfgCommon.HotkeyEnabled = SettingDialog.HotkeyEnabled
6065             _cfgCommon.HotkeyModifier = SettingDialog.HotkeyMod
6066             _cfgCommon.HotkeyKey = SettingDialog.HotkeyKey
6067             _cfgCommon.HotkeyValue = SettingDialog.HotkeyValue
6068             _cfgCommon.BlinkNewMentions = SettingDialog.BlinkNewMentions
6069             If ToolStripFocusLockMenuItem IsNot Nothing AndAlso _
6070                     ToolStripFocusLockMenuItem.IsDisposed = False Then
6071                 _cfgCommon.FocusLockToStatusText = Me.ToolStripFocusLockMenuItem.Checked
6072             End If
6073             _cfgCommon.UseAdditionalCount = SettingDialog.UseAdditionalCount
6074             _cfgCommon.MoreCountApi = SettingDialog.MoreCountApi
6075             _cfgCommon.FirstCountApi = SettingDialog.FirstCountApi
6076             _cfgCommon.SearchCountApi = SettingDialog.SearchCountApi
6077             _cfgCommon.FavoritesCountApi = SettingDialog.FavoritesCountApi
6078             _cfgCommon.UserTimelineCountApi = SettingDialog.UserTimelineCountApi
6079             _cfgCommon.TrackWord = tw.TrackWord
6080             _cfgCommon.AllAtReply = tw.AllAtReply
6081             _cfgCommon.OpenUserTimeline = SettingDialog.OpenUserTimeline
6082             _cfgCommon.ListCountApi = SettingDialog.ListCountApi
6083             _cfgCommon.UseImageService = ImageServiceCombo.SelectedIndex
6084
6085             _cfgCommon.Save()
6086         End SyncLock
6087     End Sub
6088
6089     Private Sub SaveConfigsLocal()
6090         If _ignoreConfigSave Then Exit Sub
6091         SyncLock _syncObject
6092             _modifySettingLocal = False
6093             _cfgLocal.FormSize = _mySize
6094             _cfgLocal.FormLocation = _myLoc
6095             _cfgLocal.SplitterDistance = _mySpDis
6096             _cfgLocal.PreviewDistance = _mySpDis3
6097             _cfgLocal.StatusMultiline = StatusText.Multiline
6098             _cfgLocal.StatusTextHeight = _mySpDis2
6099             _cfgLocal.StatusText = SettingDialog.Status
6100
6101             _cfgLocal.FontUnread = _fntUnread
6102             _cfgLocal.ColorUnread = _clUnread
6103             _cfgLocal.FontRead = _fntReaded
6104             _cfgLocal.ColorRead = _clReaded
6105             _cfgLocal.FontDetail = _fntDetail
6106             _cfgLocal.ColorDetail = _clDetail
6107             _cfgLocal.ColorDetailBackcolor = _clDetailBackcolor
6108             _cfgLocal.ColorDetailLink = _clDetailLink
6109             _cfgLocal.ColorFav = _clFav
6110             _cfgLocal.ColorOWL = _clOWL
6111             _cfgLocal.ColorRetweet = _clRetweet
6112             _cfgLocal.ColorSelf = _clSelf
6113             _cfgLocal.ColorAtSelf = _clAtSelf
6114             _cfgLocal.ColorTarget = _clTarget
6115             _cfgLocal.ColorAtTarget = _clAtTarget
6116             _cfgLocal.ColorAtFromTarget = _clAtFromTarget
6117             _cfgLocal.ColorAtTo = _clAtTo
6118             _cfgLocal.ColorListBackcolor = _clListBackcolor
6119             _cfgLocal.ColorInputBackcolor = _clInputBackcolor
6120             _cfgLocal.ColorInputFont = _clInputFont
6121             _cfgLocal.FontInputFont = _fntInputFont
6122
6123             _cfgLocal.BrowserPath = SettingDialog.BrowserPath
6124             _cfgLocal.UseRecommendStatus = SettingDialog.UseRecommendStatus
6125             _cfgLocal.ProxyType = SettingDialog.SelectedProxyType
6126             _cfgLocal.ProxyAddress = SettingDialog.ProxyAddress
6127             _cfgLocal.ProxyPort = SettingDialog.ProxyPort
6128             _cfgLocal.ProxyUser = SettingDialog.ProxyUser
6129             _cfgLocal.ProxyPassword = SettingDialog.ProxyPassword
6130             If _ignoreConfigSave Then Exit Sub
6131             _cfgLocal.Save()
6132         End SyncLock
6133     End Sub
6134
6135     Private Sub SaveConfigsTabs()
6136         Dim tabSetting As New SettingTabs
6137         For i As Integer = 0 To ListTab.TabPages.Count - 1
6138             If _statuses.Tabs(ListTab.TabPages(i).Text).TabType <> TabUsageType.Related Then tabSetting.Tabs.Add(_statuses.Tabs(ListTab.TabPages(i).Text))
6139         Next
6140         tabSetting.Save()
6141     End Sub
6142
6143     Private Sub SaveLogMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveLogMenuItem.Click, SaveFileMenuItem.Click
6144         Dim rslt As DialogResult = MessageBox.Show(String.Format(My.Resources.SaveLogMenuItem_ClickText1, Environment.NewLine), _
6145                 My.Resources.SaveLogMenuItem_ClickText2, _
6146                 MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)
6147         If rslt = Windows.Forms.DialogResult.Cancel Then Exit Sub
6148
6149         SaveFileDialog1.FileName = "TweenPosts" + Format(Now, "yyMMdd-HHmmss") + ".tsv"
6150         SaveFileDialog1.InitialDirectory = My.Application.Info.DirectoryPath
6151         SaveFileDialog1.Filter = My.Resources.SaveLogMenuItem_ClickText3
6152         SaveFileDialog1.FilterIndex = 0
6153         SaveFileDialog1.Title = My.Resources.SaveLogMenuItem_ClickText4
6154         SaveFileDialog1.RestoreDirectory = True
6155
6156         If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
6157             If Not SaveFileDialog1.ValidateNames Then Exit Sub
6158             Using sw As StreamWriter = New StreamWriter(SaveFileDialog1.FileName, False, Encoding.UTF8)
6159                 If rslt = Windows.Forms.DialogResult.Yes Then
6160                     'All
6161                     For idx As Integer = 0 To _curList.VirtualListSize - 1
6162                         Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
6163                         Dim protect As String = ""
6164                         If post.IsProtect Then protect = "Protect"
6165                         sw.WriteLine(post.Nickname & vbTab & _
6166                                  """" & post.TextFromApi.Replace(vbLf, "").Replace("""", """""") + """" & vbTab & _
6167                                  post.CreatedAt.ToString() & vbTab & _
6168                                  post.ScreenName & vbTab & _
6169                                  post.StatusId.ToString() & vbTab & _
6170                                  post.ImageUrl & vbTab & _
6171                                  """" & post.Text.Replace(vbLf, "").Replace("""", """""") + """" & vbTab & _
6172                                  protect)
6173                     Next
6174                 Else
6175                     For Each idx As Integer In _curList.SelectedIndices
6176                         Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
6177                         Dim protect As String = ""
6178                         If post.IsProtect Then protect = "Protect"
6179                         sw.WriteLine(post.Nickname & vbTab & _
6180                                  """" & post.TextFromApi.Replace(vbLf, "").Replace("""", """""") + """" & vbTab & _
6181                                  post.CreatedAt.ToString() & vbTab & _
6182                                  post.ScreenName & vbTab & _
6183                                  post.StatusId.ToString() & vbTab & _
6184                                  post.ImageUrl & vbTab & _
6185                                  """" & post.Text.Replace(vbLf, "").Replace("""", """""") + """" & vbTab & _
6186                                  protect)
6187                     Next
6188                 End If
6189                 sw.Close()
6190                 sw.Dispose()
6191             End Using
6192         End If
6193         Me.TopMost = SettingDialog.AlwaysTop
6194     End Sub
6195
6196     Private Sub PostBrowser_PreviewKeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles PostBrowser.PreviewKeyDown
6197         Dim State As ModifierState = GetModifierState(e.Control, e.Shift, e.Alt)
6198         If State = ModifierState.NotFlags Then Exit Sub
6199         Dim KeyRes As Boolean = CommonKeyDown(e.KeyCode, ModifierState.PostBrowser, State)
6200         If KeyRes Then
6201             e.IsInputKey = True
6202         End If
6203     End Sub
6204     Public Function TabRename(ByRef tabName As String) As Boolean
6205         'タブ名変更
6206         Dim newTabText As String = Nothing
6207         Using inputName As New InputTabName()
6208             inputName.TabName = tabName
6209             inputName.ShowDialog()
6210             If inputName.DialogResult = Windows.Forms.DialogResult.Cancel Then Return False
6211             newTabText = inputName.TabName
6212             inputName.Dispose()
6213         End Using
6214         Me.TopMost = SettingDialog.AlwaysTop
6215         If Not String.IsNullOrEmpty(newTabText) Then
6216             '新タブ名存在チェック
6217             For i As Integer = 0 To ListTab.TabCount - 1
6218                 If ListTab.TabPages(i).Text = newTabText Then
6219                     Dim tmp As String = String.Format(My.Resources.Tabs_DoubleClickText1, newTabText)
6220                     MessageBox.Show(tmp, My.Resources.Tabs_DoubleClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
6221                     Return False
6222                 End If
6223             Next
6224             'タブ名のリスト作り直し(デフォルトタブ以外は再作成)
6225             For i As Integer = 0 To ListTab.TabCount - 1
6226                 If _statuses.IsDistributableTab(ListTab.TabPages(i).Text) Then
6227                     TabDialog.RemoveTab(ListTab.TabPages(i).Text)
6228                 End If
6229                 If ListTab.TabPages(i).Text = tabName Then
6230                     ListTab.TabPages(i).Text = newTabText
6231                 End If
6232             Next
6233             _statuses.RenameTab(tabName, newTabText)
6234
6235             For i As Integer = 0 To ListTab.TabCount - 1
6236                 If _statuses.IsDistributableTab(ListTab.TabPages(i).Text) Then
6237                     If ListTab.TabPages(i).Text = tabName Then
6238                         ListTab.TabPages(i).Text = newTabText
6239                     End If
6240                     TabDialog.AddTab(ListTab.TabPages(i).Text)
6241                 End If
6242             Next
6243             SaveConfigsCommon()
6244             SaveConfigsTabs()
6245             _rclickTabName = newTabText
6246             tabName = newTabText
6247             Return True
6248         Else
6249             Return False
6250         End If
6251     End Function
6252
6253     Private Sub ListTab_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseClick
6254         If e.Button = Windows.Forms.MouseButtons.Middle Then
6255             For i As Integer = 0 To Me.ListTab.TabPages.Count - 1
6256                 If Me.ListTab.GetTabRect(i).Contains(e.Location) Then
6257                     Me.RemoveSpecifiedTab(Me.ListTab.TabPages(i).Text, True)
6258                     Me.SaveConfigsTabs()
6259                     Exit For
6260                 End If
6261             Next
6262         End If
6263     End Sub
6264
6265     Private Sub Tabs_DoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseDoubleClick
6266         Dim tn As String = ListTab.SelectedTab.Text
6267         TabRename(tn)
6268     End Sub
6269
6270     Private Sub Tabs_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseDown
6271         Dim cpos As New Point(e.X, e.Y)
6272         If e.Button = Windows.Forms.MouseButtons.Left Then
6273             For i As Integer = 0 To ListTab.TabPages.Count - 1
6274                 If Me.ListTab.GetTabRect(i).Contains(e.Location) Then
6275                     _tabDrag = True
6276                     _tabMouseDownPoint = e.Location
6277                     Exit For
6278                 End If
6279             Next
6280         Else
6281             _tabDrag = False
6282         End If
6283     End Sub
6284
6285     Private Sub Tabs_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListTab.DragEnter
6286         If e.Data.GetDataPresent(GetType(TabPage)) Then
6287             e.Effect = DragDropEffects.Move
6288         Else
6289             e.Effect = DragDropEffects.None
6290         End If
6291     End Sub
6292
6293     Private Sub Tabs_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListTab.DragDrop
6294         If Not e.Data.GetDataPresent(GetType(TabPage)) Then Exit Sub
6295
6296         _tabDrag = False
6297         Dim tn As String = ""
6298         Dim bef As Boolean
6299         Dim cpos As New Point(e.X, e.Y)
6300         Dim spos As Point = ListTab.PointToClient(cpos)
6301         Dim i As Integer
6302         For i = 0 To ListTab.TabPages.Count - 1
6303             Dim rect As Rectangle = ListTab.GetTabRect(i)
6304             If rect.Left <= spos.X AndAlso spos.X <= rect.Right AndAlso _
6305                rect.Top <= spos.Y AndAlso spos.Y <= rect.Bottom Then
6306                 tn = ListTab.TabPages(i).Text
6307                 If spos.X <= (rect.Left + rect.Right) / 2 Then
6308                     bef = True
6309                 Else
6310                     bef = False
6311                 End If
6312                 Exit For
6313             End If
6314         Next
6315
6316         'タブのないところにドロップ->最後尾へ移動
6317         If String.IsNullOrEmpty(tn) Then
6318             tn = ListTab.TabPages(ListTab.TabPages.Count - 1).Text
6319             bef = False
6320             i = ListTab.TabPages.Count - 1
6321         End If
6322
6323         Dim tp As TabPage = DirectCast(e.Data.GetData(GetType(TabPage)), TabPage)
6324         If tp.Text = tn Then Exit Sub
6325
6326         ReOrderTab(tp.Text, tn, bef)
6327     End Sub
6328
6329     Public Sub ReOrderTab(ByVal targetTabText As String, ByVal baseTabText As String, ByVal isBeforeBaseTab As Boolean)
6330         Dim baseIndex As Integer = 0
6331         For baseIndex = 0 To ListTab.TabPages.Count - 1
6332             If ListTab.TabPages(baseIndex).Text = baseTabText Then Exit For
6333         Next
6334
6335         ListTab.SuspendLayout()
6336
6337         Dim mTp As TabPage = Nothing
6338         For j As Integer = 0 To ListTab.TabPages.Count - 1
6339             If ListTab.TabPages(j).Text = targetTabText Then
6340                 mTp = ListTab.TabPages(j)
6341                 ListTab.TabPages.Remove(mTp)
6342                 If j < baseIndex Then baseIndex -= 1
6343                 Exit For
6344             End If
6345         Next
6346         If isBeforeBaseTab Then
6347             ListTab.TabPages.Insert(baseIndex, mTp)
6348         Else
6349             ListTab.TabPages.Insert(baseIndex + 1, mTp)
6350         End If
6351
6352         ListTab.ResumeLayout()
6353
6354         SaveConfigsTabs()
6355     End Sub
6356
6357     Private Sub MakeReplyOrDirectStatus(Optional ByVal isAuto As Boolean = True, Optional ByVal isReply As Boolean = True, Optional ByVal isAll As Boolean = False)
6358         'isAuto:True=先頭に挿入、False=カーソル位置に挿入
6359         'isReply:True=@,False=DM
6360         If Not StatusText.Enabled Then Exit Sub
6361         If _curList Is Nothing Then Exit Sub
6362         If _curTab Is Nothing Then Exit Sub
6363         If Not Me.ExistCurrentPost Then Exit Sub
6364
6365         ' 複数あてリプライはReplyではなく通常ポスト
6366         '↑仕様変更で全部リプライ扱いでOK(先頭ドット付加しない)
6367         '090403暫定でドットを付加しないようにだけ修正。単独と複数の処理は統合できると思われる。
6368         '090513 all @ replies 廃止の仕様変更によりドット付加に戻し(syo68k)
6369
6370         If _curList.SelectedIndices.Count > 0 Then
6371             ' アイテムが1件以上選択されている
6372             If _curList.SelectedIndices.Count = 1 AndAlso Not isAll AndAlso Me.ExistCurrentPost Then
6373                 ' 単独ユーザー宛リプライまたはDM
6374                 If (_statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.DirectMessage AndAlso isAuto) OrElse (Not isAuto AndAlso Not isReply) Then
6375                     ' ダイレクトメッセージ
6376                     StatusText.Text = "D " + _curPost.ScreenName + " " + StatusText.Text
6377                     StatusText.SelectionStart = StatusText.Text.Length
6378                     StatusText.Focus()
6379                     _reply_to_id = 0
6380                     _reply_to_name = ""
6381                     Exit Sub
6382                 End If
6383                 If String.IsNullOrEmpty(StatusText.Text) Then
6384                     '空の場合
6385
6386                     ' ステータステキストが入力されていない場合先頭に@ユーザー名を追加する
6387                     StatusText.Text = "@" + _curPost.ScreenName + " "
6388                     If _curPost.RetweetedId > 0 Then
6389                         _reply_to_id = _curPost.RetweetedId
6390                     Else
6391                         _reply_to_id = _curPost.StatusId
6392                     End If
6393                     _reply_to_name = _curPost.ScreenName
6394                 Else
6395                     '何か入力済の場合
6396
6397                     If isAuto Then
6398                         '1件選んでEnter or DoubleClick
6399                         If StatusText.Text.Contains("@" + _curPost.ScreenName + " ") Then
6400                             If _reply_to_id > 0 AndAlso _reply_to_name = _curPost.ScreenName Then
6401                                 '返信先書き換え
6402                                 If _curPost.RetweetedId > 0 Then
6403                                     _reply_to_id = _curPost.RetweetedId
6404                                 Else
6405                                     _reply_to_id = _curPost.StatusId
6406                                 End If
6407                                 _reply_to_name = _curPost.ScreenName
6408                             End If
6409                             Exit Sub
6410                         End If
6411                         If Not StatusText.Text.StartsWith("@") Then
6412                             '文頭@以外
6413                             If StatusText.Text.StartsWith(". ") Then
6414                                 ' 複数リプライ
6415                                 StatusText.Text = StatusText.Text.Insert(2, "@" + _curPost.ScreenName + " ")
6416                                 _reply_to_id = 0
6417                                 _reply_to_name = ""
6418                             Else
6419                                 ' 単独リプライ
6420                                 StatusText.Text = "@" + _curPost.ScreenName + " " + StatusText.Text
6421                                 If _curPost.RetweetedId > 0 Then
6422                                     _reply_to_id = _curPost.RetweetedId
6423                                 Else
6424                                     _reply_to_id = _curPost.StatusId
6425                                 End If
6426                                 _reply_to_name = _curPost.ScreenName
6427                             End If
6428                         Else
6429                             '文頭@
6430                             ' 複数リプライ
6431                             StatusText.Text = ". @" + _curPost.ScreenName + " " + StatusText.Text
6432                             'StatusText.Text = "@" + _curPost.ScreenName + " " + StatusText.Text
6433                             _reply_to_id = 0
6434                             _reply_to_name = ""
6435                         End If
6436                     Else
6437                         '1件選んでCtrl-Rの場合(返信先操作せず)
6438                         Dim sidx As Integer = StatusText.SelectionStart
6439                         Dim id As String = "@" + _curPost.ScreenName + " "
6440                         If sidx > 0 Then
6441                             If StatusText.Text.Substring(sidx - 1, 1) <> " " Then
6442                                 id = " " + id
6443                             End If
6444                         End If
6445                         StatusText.Text = StatusText.Text.Insert(sidx, id)
6446                         sidx += id.Length
6447                         'If StatusText.Text.StartsWith("@") Then
6448                         '    '複数リプライ
6449                         '    StatusText.Text = ". " + StatusText.Text.Insert(sidx, " @" + _curPost.ScreenName + " ")
6450                         '    sidx += 5 + _curPost.ScreenName.Length
6451                         'Else
6452                         '    ' 複数リプライ
6453                         '    StatusText.Text = StatusText.Text.Insert(sidx, " @" + _curPost.ScreenName + " ")
6454                         '    sidx += 3 + _curPost.ScreenName.Length
6455                         'End If
6456                         StatusText.SelectionStart = sidx
6457                         StatusText.Focus()
6458                         '_reply_to_id = 0
6459                         '_reply_to_name = Nothing
6460                         Exit Sub
6461                     End If
6462                 End If
6463             Else
6464                 ' 複数リプライ
6465                 If Not isAuto AndAlso Not isReply Then Exit Sub
6466
6467                 'C-S-rか、複数の宛先を選択中にEnter/DoubleClick/C-r/C-S-r
6468
6469                 If isAuto Then
6470                     'Enter or DoubleClick
6471
6472                     Dim sTxt As String = StatusText.Text
6473                     If Not sTxt.StartsWith(". ") Then
6474                         sTxt = ". " + sTxt
6475                         _reply_to_id = 0
6476                         _reply_to_name = ""
6477                     End If
6478                     For cnt As Integer = 0 To _curList.SelectedIndices.Count - 1
6479                         Dim post As PostClass = _statuses.Item(_curTab.Text, _curList.SelectedIndices(cnt))
6480                         If Not sTxt.Contains("@" + post.ScreenName + " ") Then
6481                             sTxt = sTxt.Insert(2, "@" + post.ScreenName + " ")
6482                             'sTxt = "@" + post.ScreenName + " " + sTxt
6483                         End If
6484                     Next
6485                     StatusText.Text = sTxt
6486                 Else
6487                     'C-S-r or C-r
6488                     If _curList.SelectedIndices.Count > 1 Then
6489                         '複数ポスト選択
6490
6491                         Dim ids As String = ""
6492                         Dim sidx As Integer = StatusText.SelectionStart
6493                         For cnt As Integer = 0 To _curList.SelectedIndices.Count - 1
6494                             Dim post As PostClass = _statuses.Item(_curTab.Text, _curList.SelectedIndices(cnt))
6495                             If Not ids.Contains("@" + post.ScreenName + " ") AndAlso _
6496                                Not post.ScreenName.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase) Then
6497                                 ids += "@" + post.ScreenName + " "
6498                             End If
6499                             If isAll Then
6500                                 For Each nm As String In post.ReplyToList
6501                                     If Not ids.Contains("@" + nm + " ") AndAlso _
6502                                        Not nm.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase) Then
6503                                         Dim m As Match = Regex.Match(post.TextFromApi, "[@@](?<id>" + nm + ")([^a-zA-Z0-9]|$)", RegexOptions.IgnoreCase)
6504                                         If m.Success Then
6505                                             ids += "@" + m.Result("${id}") + " "
6506                                         Else
6507                                             ids += "@" + nm + " "
6508                                         End If
6509                                     End If
6510                                 Next
6511                             End If
6512                         Next
6513                         If ids.Length = 0 Then Exit Sub
6514                         If Not StatusText.Text.StartsWith(". ") Then
6515                             StatusText.Text = ". " + StatusText.Text
6516                             sidx += 2
6517                             _reply_to_id = 0
6518                             _reply_to_name = ""
6519                         End If
6520                         If sidx > 0 Then
6521                             If StatusText.Text.Substring(sidx - 1, 1) <> " " Then
6522                                 ids = " " + ids
6523                             End If
6524                         End If
6525                         StatusText.Text = StatusText.Text.Insert(sidx, ids)
6526                         sidx += ids.Length
6527                         'If StatusText.Text.StartsWith("@") Then
6528                         '    StatusText.Text = ". " + StatusText.Text.Insert(sidx, ids)
6529                         '    sidx += 2 + ids.Length
6530                         'Else
6531                         '    StatusText.Text = StatusText.Text.Insert(sidx, ids)
6532                         '    sidx += 1 + ids.Length
6533                         'End If
6534                         StatusText.SelectionStart = sidx
6535                         StatusText.Focus()
6536                         Exit Sub
6537                     Else
6538                         '1件のみ選択のC-S-r(返信元付加する可能性あり)
6539
6540                         Dim ids As String = ""
6541                         Dim sidx As Integer = StatusText.SelectionStart
6542                         Dim post As PostClass = _curPost
6543                         If Not ids.Contains("@" + post.ScreenName + " ") AndAlso _
6544                            Not post.ScreenName.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase) Then
6545                             ids += "@" + post.ScreenName + " "
6546                         End If
6547                         For Each nm As String In post.ReplyToList
6548                             If Not ids.Contains("@" + nm + " ") AndAlso _
6549                                Not nm.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase) Then
6550                                 Dim m As Match = Regex.Match(post.TextFromApi, "[@@](?<id>" + nm + ")([^a-zA-Z0-9]|$)", RegexOptions.IgnoreCase)
6551                                 If m.Success Then
6552                                     ids += "@" + m.Result("${id}") + " "
6553                                 Else
6554                                     ids += "@" + nm + " "
6555                                 End If
6556                             End If
6557                         Next
6558                         If Not String.IsNullOrEmpty(post.RetweetedBy) Then
6559                             If Not ids.Contains("@" + post.RetweetedBy + " ") AndAlso _
6560                                Not post.RetweetedBy.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase) Then
6561                                 ids += "@" + post.RetweetedBy + " "
6562                             End If
6563                         End If
6564                         If ids.Length = 0 Then Exit Sub
6565                         If String.IsNullOrEmpty(StatusText.Text) Then
6566                             '未入力の場合のみ返信先付加
6567                             StatusText.Text = ids
6568                             StatusText.SelectionStart = ids.Length
6569                             StatusText.Focus()
6570                             If post.RetweetedId > 0 Then
6571                                 _reply_to_id = post.RetweetedId
6572                             Else
6573                                 _reply_to_id = post.StatusId
6574                             End If
6575                             _reply_to_name = post.ScreenName
6576                             Exit Sub
6577                         End If
6578
6579                         If sidx > 0 Then
6580                             If StatusText.Text.Substring(sidx - 1, 1) <> " " Then
6581                                 ids = " " + ids
6582                             End If
6583                         End If
6584                         StatusText.Text = StatusText.Text.Insert(sidx, ids)
6585                         sidx += ids.Length
6586                         StatusText.SelectionStart = sidx
6587                         StatusText.Focus()
6588                         Exit Sub
6589                     End If
6590                 End If
6591             End If
6592             StatusText.SelectionStart = StatusText.Text.Length
6593             StatusText.Focus()
6594         End If
6595     End Sub
6596
6597     Private Sub ListTab_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseUp
6598         _tabDrag = False
6599     End Sub
6600
6601     Private Sub RefreshTasktrayIcon(ByVal forceRefresh As Boolean)
6602         If _colorize Then Colorize()
6603         If Not TimerRefreshIcon.Enabled Then Exit Sub
6604         Static iconCnt As Integer = 0
6605         Static blinkCnt As Integer = 0
6606         Static blink As Boolean = False
6607         Static idle As Boolean = False
6608         'Static usCheckCnt As Integer = 0
6609
6610         'Static iconDlListTopItem As ListViewItem = Nothing
6611
6612         If forceRefresh Then idle = False
6613
6614         'If DirectCast(ListTab.SelectedTab.Tag, ListView).TopItem Is iconDlListTopItem Then
6615         '    DirectCast(Me.TIconDic, ImageDictionary).PauseGetImage = False
6616         'Else
6617         '    DirectCast(Me.TIconDic, ImageDictionary).PauseGetImage = True
6618         'End If
6619         'iconDlListTopItem = DirectCast(ListTab.SelectedTab.Tag, ListView).TopItem
6620
6621         iconCnt += 1
6622         blinkCnt += 1
6623         'usCheckCnt += 1
6624
6625         'If usCheckCnt > 300 Then    '1min
6626         '    usCheckCnt = 0
6627         '    If Not Me.IsReceivedUserStream Then
6628         '        TraceOut("ReconnectUserStream")
6629         '        tw.ReconnectUserStream()
6630         '    End If
6631         'End If
6632
6633         Dim busy As Boolean = False
6634         For Each bw As BackgroundWorker In Me._bw
6635             If bw IsNot Nothing AndAlso bw.IsBusy Then
6636                 busy = True
6637                 Exit For
6638             End If
6639         Next
6640
6641         If iconCnt > 3 Then
6642             iconCnt = 0
6643         End If
6644         If blinkCnt > 10 Then
6645             blinkCnt = 0
6646             '未保存の変更を保存
6647             SaveConfigsAll(True)
6648         End If
6649
6650         If busy Then
6651             NotifyIcon1.Icon = NIconRefresh(iconCnt)
6652             idle = False
6653             _myStatusError = False
6654             Exit Sub
6655         End If
6656
6657         Dim tb As TabClass = _statuses.GetTabByType(TabUsageType.Mentions)
6658         If SettingDialog.ReplyIconState <> REPLY_ICONSTATE.None AndAlso tb IsNot Nothing AndAlso tb.UnreadCount > 0 Then
6659             If blinkCnt > 0 Then Exit Sub
6660             blink = Not blink
6661             If blink OrElse SettingDialog.ReplyIconState = REPLY_ICONSTATE.StaticIcon Then
6662                 NotifyIcon1.Icon = ReplyIcon
6663             Else
6664                 NotifyIcon1.Icon = ReplyIconBlink
6665             End If
6666             idle = False
6667             Exit Sub
6668         End If
6669
6670         If idle Then Exit Sub
6671         idle = True
6672         '優先度:エラー→オフライン→アイドル
6673         'エラーは更新アイコンでクリアされる
6674         If _myStatusError Then
6675             NotifyIcon1.Icon = NIconAtRed
6676             Exit Sub
6677         End If
6678         If _myStatusOnline Then
6679             NotifyIcon1.Icon = NIconAt
6680         Else
6681             NotifyIcon1.Icon = NIconAtSmoke
6682         End If
6683     End Sub
6684
6685     Private Sub TimerRefreshIcon_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerRefreshIcon.Tick
6686         '200ms
6687         Me.RefreshTasktrayIcon(False)
6688     End Sub
6689
6690     Private Sub ContextMenuTabProperty_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuTabProperty.Opening
6691         '右クリックの場合はタブ名が設定済。アプリケーションキーの場合は現在のタブを対象とする
6692         If String.IsNullOrEmpty(_rclickTabName) OrElse sender IsNot ContextMenuTabProperty Then
6693             If ListTab IsNot Nothing AndAlso ListTab.SelectedTab IsNot Nothing Then
6694                 _rclickTabName = ListTab.SelectedTab.Text
6695             Else
6696                 Exit Sub
6697             End If
6698         End If
6699
6700         If _statuses Is Nothing Then Exit Sub
6701         If _statuses.Tabs Is Nothing Then Exit Sub
6702
6703         Dim tb As TabClass = _statuses.Tabs(_rclickTabName)
6704         If tb Is Nothing Then Exit Sub
6705
6706         NotifyDispMenuItem.Checked = tb.Notify
6707         Me.NotifyTbMenuItem.Checked = tb.Notify
6708
6709         soundfileListup = True
6710         SoundFileComboBox.Items.Clear()
6711         Me.SoundFileTbComboBox.Items.Clear()
6712         SoundFileComboBox.Items.Add("")
6713         Me.SoundFileTbComboBox.Items.Add("")
6714         Dim oDir As IO.DirectoryInfo = New IO.DirectoryInfo(My.Application.Info.DirectoryPath + IO.Path.DirectorySeparatorChar)
6715         If IO.Directory.Exists(IO.Path.Combine(My.Application.Info.DirectoryPath, "Sounds")) Then
6716             oDir = oDir.GetDirectories("Sounds")(0)
6717         End If
6718         For Each oFile As IO.FileInfo In oDir.GetFiles("*.wav")
6719             SoundFileComboBox.Items.Add(oFile.Name)
6720             Me.SoundFileTbComboBox.Items.Add(oFile.Name)
6721         Next
6722         Dim idx As Integer = SoundFileComboBox.Items.IndexOf(tb.SoundFile)
6723         If idx = -1 Then idx = 0
6724         SoundFileComboBox.SelectedIndex = idx
6725         Me.SoundFileTbComboBox.SelectedIndex = idx
6726         soundfileListup = False
6727         UreadManageMenuItem.Checked = tb.UnreadManage
6728         Me.UnreadMngTbMenuItem.Checked = tb.UnreadManage
6729
6730         TabMenuControl(_rclickTabName)
6731     End Sub
6732
6733     Private Sub TabMenuControl(ByVal tabName As String)
6734         If _statuses.Tabs(tabName).TabType <> TabUsageType.Mentions AndAlso _statuses.IsDefaultTab(tabName) Then
6735             FilterEditMenuItem.Enabled = True
6736             Me.EditRuleTbMenuItem.Enabled = True
6737             DeleteTabMenuItem.Enabled = False
6738             Me.DeleteTbMenuItem.Enabled = False
6739         ElseIf _statuses.Tabs(tabName).TabType = TabUsageType.Mentions Then
6740             FilterEditMenuItem.Enabled = True
6741             Me.EditRuleTbMenuItem.Enabled = True
6742             DeleteTabMenuItem.Enabled = False
6743             Me.DeleteTbMenuItem.Enabled = False
6744         Else
6745             FilterEditMenuItem.Enabled = True
6746             Me.EditRuleTbMenuItem.Enabled = True
6747             DeleteTabMenuItem.Enabled = True
6748             Me.DeleteTbMenuItem.Enabled = True
6749         End If
6750     End Sub
6751
6752     Private Sub UreadManageMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UreadManageMenuItem.Click, UnreadMngTbMenuItem.Click
6753         UreadManageMenuItem.Checked = DirectCast(sender, ToolStripMenuItem).Checked
6754         Me.UnreadMngTbMenuItem.Checked = UreadManageMenuItem.Checked
6755
6756         If String.IsNullOrEmpty(_rclickTabName) Then Exit Sub
6757         ChangeTabUnreadManage(_rclickTabName, UreadManageMenuItem.Checked)
6758
6759         SaveConfigsTabs()
6760     End Sub
6761
6762     Public Sub ChangeTabUnreadManage(ByVal tabName As String, ByVal isManage As Boolean)
6763
6764         Dim idx As Integer
6765         For idx = 0 To ListTab.TabCount
6766             If ListTab.TabPages(idx).Text = tabName Then Exit For
6767         Next
6768
6769         _statuses.SetTabUnreadManage(tabName, isManage)
6770         If SettingDialog.TabIconDisp Then
6771             If _statuses.Tabs(tabName).UnreadCount > 0 Then
6772                 ListTab.TabPages(idx).ImageIndex = 0
6773             Else
6774                 ListTab.TabPages(idx).ImageIndex = -1
6775             End If
6776         End If
6777
6778         If _curTab.Text = tabName Then
6779             _itemCache = Nothing
6780             _postCache = Nothing
6781             _curList.Refresh()
6782         End If
6783
6784         SetMainWindowTitle()
6785         SetStatusLabelUrl()
6786         If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
6787     End Sub
6788
6789     Private Sub NotifyDispMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NotifyDispMenuItem.Click, NotifyTbMenuItem.Click
6790         NotifyDispMenuItem.Checked = DirectCast(sender, ToolStripMenuItem).Checked
6791         Me.NotifyTbMenuItem.Checked = NotifyDispMenuItem.Checked
6792
6793         If String.IsNullOrEmpty(_rclickTabName) Then Exit Sub
6794
6795         _statuses.Tabs(_rclickTabName).Notify = NotifyDispMenuItem.Checked
6796
6797         SaveConfigsTabs()
6798     End Sub
6799
6800     Private Sub SoundFileComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SoundFileComboBox.SelectedIndexChanged, SoundFileTbComboBox.SelectedIndexChanged
6801         If soundfileListup OrElse _rclickTabName = "" Then Exit Sub
6802
6803         _statuses.Tabs(_rclickTabName).SoundFile = DirectCast(DirectCast(sender, ToolStripComboBox).SelectedItem, String)
6804
6805         SaveConfigsTabs()
6806     End Sub
6807
6808     Private Sub DeleteTabMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DeleteTabMenuItem.Click, DeleteTbMenuItem.Click
6809         If String.IsNullOrEmpty(_rclickTabName) OrElse sender Is Me.DeleteTbMenuItem Then _rclickTabName = ListTab.SelectedTab.Text
6810
6811         RemoveSpecifiedTab(_rclickTabName, True)
6812         SaveConfigsTabs()
6813     End Sub
6814
6815     Private Sub FilterEditMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FilterEditMenuItem.Click, EditRuleTbMenuItem.Click
6816
6817         If String.IsNullOrEmpty(_rclickTabName) Then _rclickTabName = _statuses.GetTabByType(TabUsageType.Home).TabName
6818         fltDialog.SetCurrent(_rclickTabName)
6819         fltDialog.ShowDialog()
6820         Me.TopMost = SettingDialog.AlwaysTop
6821
6822         Try
6823             Me.Cursor = Cursors.WaitCursor
6824             _itemCache = Nothing
6825             _postCache = Nothing
6826             _curPost = Nothing
6827             _curItemIndex = -1
6828             _statuses.FilterAll()
6829             For Each tb As TabPage In ListTab.TabPages
6830                 DirectCast(tb.Tag, DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
6831                 If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
6832                     If SettingDialog.TabIconDisp Then
6833                         tb.ImageIndex = 0
6834                     End If
6835                 Else
6836                     If SettingDialog.TabIconDisp Then
6837                         tb.ImageIndex = -1
6838                     End If
6839                 End If
6840             Next
6841             If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
6842         Finally
6843             Me.Cursor = Cursors.Default
6844         End Try
6845         SaveConfigsTabs()
6846     End Sub
6847
6848     Private Sub AddTabMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddTabMenuItem.Click, CreateTbMenuItem.Click
6849         Dim tabName As String = Nothing
6850         Dim tabUsage As TabUsageType
6851         Using inputName As New InputTabName()
6852             inputName.TabName = _statuses.GetUniqueTabName
6853             inputName.IsShowUsage = True
6854             inputName.ShowDialog()
6855             If inputName.DialogResult = Windows.Forms.DialogResult.Cancel Then Exit Sub
6856             tabName = inputName.TabName
6857             tabUsage = inputName.Usage
6858             inputName.Dispose()
6859         End Using
6860         Me.TopMost = SettingDialog.AlwaysTop
6861         If Not String.IsNullOrEmpty(tabName) Then
6862             'List対応
6863             Dim list As ListElement = Nothing
6864             If tabUsage = TabUsageType.Lists Then
6865                 Using listAvail As New ListAvailable
6866                     If listAvail.ShowDialog(Me) = Windows.Forms.DialogResult.Cancel Then Exit Sub
6867                     If listAvail.SelectedList Is Nothing Then Exit Sub
6868                     list = listAvail.SelectedList
6869                 End Using
6870             End If
6871             If Not AddNewTab(tabName, False, tabUsage, list) Then
6872                 Dim tmp As String = String.Format(My.Resources.AddTabMenuItem_ClickText1, tabName)
6873                 MessageBox.Show(tmp, My.Resources.AddTabMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
6874             Else
6875                 '成功
6876                 _statuses.AddTab(tabName, tabUsage, list)
6877                 SaveConfigsTabs()
6878                 If tabUsage = TabUsageType.PublicSearch Then
6879                     ListTab.SelectedIndex = ListTab.TabPages.Count - 1
6880                     ListTabSelect(ListTab.TabPages(ListTab.TabPages.Count - 1))
6881                     ListTab.SelectedTab.Controls("panelSearch").Controls("comboSearch").Focus()
6882                 End If
6883                 If tabUsage = TabUsageType.Lists Then
6884                     ListTab.SelectedIndex = ListTab.TabPages.Count - 1
6885                     ListTabSelect(ListTab.TabPages(ListTab.TabPages.Count - 1))
6886                     GetTimeline(WORKERTYPE.List, 1, 0, tabName)
6887                 End If
6888             End If
6889         End If
6890     End Sub
6891
6892     Private Sub TabMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TabMenuItem.Click, CreateTabRuleOpMenuItem.Click
6893         '選択発言を元にフィルタ追加
6894         For Each idx As Integer In _curList.SelectedIndices
6895             Dim tabName As String = ""
6896             'タブ選択(or追加)
6897             If Not SelectTab(tabName) Then Exit Sub
6898
6899             fltDialog.SetCurrent(tabName)
6900             If _statuses.Item(_curTab.Text, idx).RetweetedId = 0 Then
6901                 fltDialog.AddNewFilter(_statuses.Item(_curTab.Text, idx).ScreenName, _statuses.Item(_curTab.Text, idx).TextFromApi)
6902             Else
6903                 fltDialog.AddNewFilter(_statuses.Item(_curTab.Text, idx).RetweetedBy, _statuses.Item(_curTab.Text, idx).TextFromApi)
6904             End If
6905             fltDialog.ShowDialog()
6906             Me.TopMost = SettingDialog.AlwaysTop
6907         Next
6908
6909         Try
6910             Me.Cursor = Cursors.WaitCursor
6911             _itemCache = Nothing
6912             _postCache = Nothing
6913             _curPost = Nothing
6914             _curItemIndex = -1
6915             _statuses.FilterAll()
6916             For Each tb As TabPage In ListTab.TabPages
6917                 DirectCast(tb.Tag, DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
6918                 If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
6919                     If SettingDialog.TabIconDisp Then
6920                         tb.ImageIndex = 0
6921                     End If
6922                 Else
6923                     If SettingDialog.TabIconDisp Then
6924                         tb.ImageIndex = -1
6925                     End If
6926                 End If
6927             Next
6928             If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
6929         Finally
6930             Me.Cursor = Cursors.Default
6931         End Try
6932         SaveConfigsTabs()
6933         If Me.ListTab.SelectedTab IsNot Nothing AndAlso
6934             DirectCast(Me.ListTab.SelectedTab.Tag, DetailsListView).SelectedIndices.Count > 0 Then
6935             _curPost = _statuses.Item(Me.ListTab.SelectedTab.Text, DirectCast(Me.ListTab.SelectedTab.Tag, DetailsListView).SelectedIndices(0))
6936         End If
6937     End Sub
6938
6939     Protected Overrides Function ProcessDialogKey( _
6940         ByVal keyData As Keys) As Boolean
6941         'TextBox1でEnterを押してもビープ音が鳴らないようにする
6942         If (keyData And Keys.KeyCode) = Keys.Enter Then
6943             If StatusText.Focused Then
6944                 Dim _NewLine As Boolean = False
6945                 Dim _Post As Boolean = False
6946
6947                 If SettingDialog.PostCtrlEnter Then 'Ctrl+Enter投稿時
6948                     If StatusText.Multiline Then
6949                         If (keyData And Keys.Shift) = Keys.Shift AndAlso (keyData And Keys.Control) <> Keys.Control Then _NewLine = True
6950
6951                         If (keyData And Keys.Control) = Keys.Control Then _Post = True
6952                     Else
6953                         If ((keyData And Keys.Control) = Keys.Control) Then _Post = True
6954                     End If
6955
6956                 ElseIf SettingDialog.PostShiftEnter Then 'SHift+Enter投稿時
6957                     If StatusText.Multiline Then
6958                         If (keyData And Keys.Control) = Keys.Control AndAlso (keyData And Keys.Shift) <> Keys.Shift Then _NewLine = True
6959
6960                         If (keyData And Keys.Shift) = Keys.Shift Then _Post = True
6961                     Else
6962                         If ((keyData And Keys.Shift) = Keys.Shift) Then _Post = True
6963                     End If
6964
6965                 Else 'Enter投稿時
6966                     If StatusText.Multiline Then
6967                         If (keyData And Keys.Shift) = Keys.Shift AndAlso (keyData And Keys.Control) <> Keys.Control Then _NewLine = True
6968
6969                         If ((keyData And Keys.Control) <> Keys.Control AndAlso (keyData And Keys.Shift) <> Keys.Shift) OrElse _
6970                             ((keyData And Keys.Control) = Keys.Control AndAlso (keyData And Keys.Shift) = Keys.Shift) Then _Post = True
6971                     Else
6972                         If ((keyData And Keys.Shift) = Keys.Shift) OrElse _
6973                            (((keyData And Keys.Control) <> Keys.Control) AndAlso _
6974                             ((keyData And Keys.Shift) <> Keys.Shift)) Then _Post = True
6975                     End If
6976                 End If
6977
6978                 If _NewLine Then
6979                     Dim pos1 As Integer = StatusText.SelectionStart
6980                     If StatusText.SelectionLength > 0 Then
6981                         StatusText.Text = StatusText.Text.Remove(pos1, StatusText.SelectionLength)  '選択状態文字列削除
6982                     End If
6983                     StatusText.Text = StatusText.Text.Insert(pos1, Environment.NewLine)  '改行挿入
6984                     StatusText.SelectionStart = pos1 + Environment.NewLine.Length    'カーソルを改行の次の文字へ移動
6985                     Return True
6986                 ElseIf _Post Then
6987                     PostButton_Click(Nothing, Nothing)
6988                     Return True
6989                 End If
6990             ElseIf _statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.PublicSearch AndAlso _
6991                     (ListTab.SelectedTab.Controls("panelSearch").Controls("comboSearch").Focused OrElse _
6992                     ListTab.SelectedTab.Controls("panelSearch").Controls("comboLang").Focused) Then
6993                 Me.SearchButton_Click(ListTab.SelectedTab.Controls("panelSearch").Controls("comboSearch"), Nothing)
6994                 Return True
6995             End If
6996         End If
6997
6998         Return MyBase.ProcessDialogKey(keyData)
6999     End Function
7000
7001     Private Sub ReplyAllStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReplyAllStripMenuItem.Click, ReplyAllOpMenuItem.Click
7002         MakeReplyOrDirectStatus(False, True, True)
7003     End Sub
7004
7005     Private Sub IDRuleMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IDRuleMenuItem.Click, CreateIdRuleOpMenuItem.Click
7006         Dim tabName As String = ""
7007
7008         '未選択なら処理終了
7009         If _curList.SelectedIndices.Count = 0 Then Exit Sub
7010
7011         'タブ選択(or追加)
7012         If Not SelectTab(tabName) Then Exit Sub
7013
7014         Dim mv As Boolean = False
7015         Dim mk As Boolean = False
7016         MoveOrCopy(mv, mk)
7017
7018         Dim ids As New List(Of String)
7019         For Each idx As Integer In _curList.SelectedIndices
7020             Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
7021             If Not ids.Contains(post.ScreenName) Then
7022                 Dim fc As New FiltersClass
7023                 ids.Add(post.ScreenName)
7024                 If post.RetweetedId = 0 Then
7025                     fc.NameFilter = post.ScreenName
7026                 Else
7027                     fc.NameFilter = post.RetweetedBy
7028                 End If
7029                 fc.SearchBoth = True
7030                 fc.MoveFrom = mv
7031                 fc.SetMark = mk
7032                 fc.UseRegex = False
7033                 fc.SearchUrl = False
7034                 _statuses.Tabs(tabName).AddFilter(fc)
7035             End If
7036         Next
7037         If ids.Count <> 0 Then
7038             Dim atids As New List(Of String)
7039             For Each id As String In ids
7040                 atids.Add("@" + id)
7041             Next
7042             Dim cnt As Integer = AtIdSupl.ItemCount
7043             AtIdSupl.AddRangeItem(atids.ToArray)
7044             If AtIdSupl.ItemCount <> cnt Then _modifySettingAtId = True
7045         End If
7046
7047         Try
7048             Me.Cursor = Cursors.WaitCursor
7049             _itemCache = Nothing
7050             _postCache = Nothing
7051             _curPost = Nothing
7052             _curItemIndex = -1
7053             _statuses.FilterAll()
7054             For Each tb As TabPage In ListTab.TabPages
7055                 DirectCast(tb.Tag, DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
7056                 If _statuses.ContainsTab(tb.Text) Then
7057                     If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
7058                         If SettingDialog.TabIconDisp Then
7059                             tb.ImageIndex = 0
7060                         End If
7061                     Else
7062                         If SettingDialog.TabIconDisp Then
7063                             tb.ImageIndex = -1
7064                         End If
7065                     End If
7066                 End If
7067             Next
7068             If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
7069         Finally
7070             Me.Cursor = Cursors.Default
7071         End Try
7072         SaveConfigsTabs()
7073     End Sub
7074
7075     Private Function SelectTab(ByRef tabName As String) As Boolean
7076         Do
7077             '振り分け先タブ選択
7078             If TabDialog.ShowDialog = Windows.Forms.DialogResult.Cancel Then
7079                 Me.TopMost = SettingDialog.AlwaysTop
7080                 Return False
7081             End If
7082             Me.TopMost = SettingDialog.AlwaysTop
7083             tabName = TabDialog.SelectedTabName
7084
7085             ListTab.SelectedTab.Focus()
7086             '新規タブを選択→タブ作成
7087             If tabName = My.Resources.IDRuleMenuItem_ClickText1 Then
7088                 Using inputName As New InputTabName()
7089                     inputName.TabName = _statuses.GetUniqueTabName
7090                     inputName.ShowDialog()
7091                     If inputName.DialogResult = Windows.Forms.DialogResult.Cancel Then Return False
7092                     tabName = inputName.TabName
7093                     inputName.Dispose()
7094                 End Using
7095                 Me.TopMost = SettingDialog.AlwaysTop
7096                 If Not String.IsNullOrEmpty(tabName) Then
7097                     If Not AddNewTab(tabName, False, TabUsageType.UserDefined) Then
7098                         Dim tmp As String = String.Format(My.Resources.IDRuleMenuItem_ClickText2, tabName)
7099                         MessageBox.Show(tmp, My.Resources.IDRuleMenuItem_ClickText3, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
7100                         'もう一度タブ名入力
7101                     Else
7102                         _statuses.AddTab(tabName, TabUsageType.UserDefined, Nothing)
7103                         Return True
7104                     End If
7105                 End If
7106             Else
7107                 '既存タブを選択
7108                 Return True
7109             End If
7110         Loop While True
7111
7112     End Function
7113
7114     Private Sub MoveOrCopy(ByRef move As Boolean, ByRef mark As Boolean)
7115         With Block
7116             '移動するか?
7117             Dim _tmp As String = String.Format(My.Resources.IDRuleMenuItem_ClickText4, Environment.NewLine)
7118             If MessageBox.Show(_tmp, My.Resources.IDRuleMenuItem_ClickText5, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
7119                 move = False
7120             Else
7121                 move = True
7122             End If
7123         End With
7124         If Not move Then
7125             'マークするか?
7126             Dim _tmp As String = String.Format(My.Resources.IDRuleMenuItem_ClickText6, vbCrLf)
7127             If MessageBox.Show(_tmp, My.Resources.IDRuleMenuItem_ClickText7, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
7128                 mark = True
7129             Else
7130                 mark = False
7131             End If
7132         End If
7133     End Sub
7134     Private Sub CopySTOTMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CopySTOTMenuItem.Click
7135         Me.CopyStot()
7136     End Sub
7137
7138     Private Sub CopyURLMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CopyURLMenuItem.Click
7139         Me.CopyIdUri()
7140     End Sub
7141
7142     Private Sub SelectAllMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectAllMenuItem.Click, SelAllOpMenuItem.Click
7143         If StatusText.Focused Then
7144             ' 発言欄でのCtrl+A
7145             StatusText.SelectAll()
7146         Else
7147             ' ListView上でのCtrl+A
7148             For i As Integer = 0 To _curList.VirtualListSize - 1
7149                 _curList.SelectedIndices.Add(i)
7150             Next
7151         End If
7152     End Sub
7153
7154     Private Sub MoveMiddle()
7155         Dim _item As ListViewItem
7156         Dim idx1 As Integer
7157         Dim idx2 As Integer
7158
7159         If _curList.SelectedIndices.Count = 0 Then Exit Sub
7160
7161         Dim idx As Integer = _curList.SelectedIndices(0)
7162
7163         _item = _curList.GetItemAt(0, 25)
7164         If _item Is Nothing Then
7165             idx1 = 0
7166         Else
7167             idx1 = _item.Index
7168         End If
7169         _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1)
7170         If _item Is Nothing Then
7171             idx2 = _curList.VirtualListSize - 1
7172         Else
7173             idx2 = _item.Index
7174         End If
7175
7176         idx -= Math.Abs(idx1 - idx2) \ 2
7177         If idx < 0 Then idx = 0
7178
7179         _curList.EnsureVisible(_curList.VirtualListSize - 1)
7180         _curList.EnsureVisible(idx)
7181     End Sub
7182
7183     Private Sub OpenURLMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenURLMenuItem.Click, OpenUrlOpMenuItem.Click
7184         If PostBrowser.Document.Links.Count > 0 Then
7185             UrlDialog.ClearUrl()
7186
7187             Dim openUrlStr As String = ""
7188
7189             If PostBrowser.Document.Links.Count = 1 Then
7190                 Dim urlStr As String = ""
7191                 Try
7192                     urlStr = IDNDecode(PostBrowser.Document.Links(0).GetAttribute("href"))
7193                 Catch ex As ArgumentException
7194                     '変なHTML?
7195                     Exit Sub
7196                 End Try
7197                 If String.IsNullOrEmpty(urlStr) Then Exit Sub
7198                 openUrlStr = urlEncodeMultibyteChar(urlStr)
7199             Else
7200                 For Each linkElm As HtmlElement In PostBrowser.Document.Links
7201                     Dim urlStr As String = ""
7202                     Dim linkText As String = ""
7203                     Try
7204                         urlStr = IDNDecode(linkElm.GetAttribute("href"))
7205                         linkText = linkElm.InnerText
7206                         If Not linkText.StartsWith("http") AndAlso Not linkText.StartsWith("#") Then
7207                             linkText = "@" + linkText
7208                         End If
7209                     Catch ex As ArgumentException
7210                         '変なHTML?
7211                         Exit Sub
7212                     End Try
7213                     If String.IsNullOrEmpty(urlStr) Then Continue For
7214                     UrlDialog.AddUrl(New OpenUrlItem(linkText, urlEncodeMultibyteChar(urlStr)))
7215                 Next
7216                 Try
7217                     If UrlDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
7218                         openUrlStr = UrlDialog.SelectedUrl
7219                     End If
7220                 Catch ex As Exception
7221                     Exit Sub
7222                 End Try
7223                 Me.TopMost = SettingDialog.AlwaysTop
7224             End If
7225             If String.IsNullOrEmpty(openUrlStr) Then Exit Sub
7226
7227             If openUrlStr.StartsWith("http://twitter.com/search?q=%23") OrElse _
7228                openUrlStr.StartsWith("https://twitter.com/search?q=%23") Then
7229                 'ハッシュタグの場合は、タブで開く
7230                 Dim urlStr As String = HttpUtility.UrlDecode(openUrlStr)
7231                 Dim hash As String = urlStr.Substring(urlStr.IndexOf("#"))
7232                 HashSupl.AddItem(hash)
7233                 HashMgr.AddHashToHistory(hash.Trim, False)
7234                 AddNewTabForSearch(hash)
7235                 Exit Sub
7236             Else
7237                 Dim m As Match = Regex.Match(openUrlStr, "^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)$")
7238                 If SettingDialog.OpenUserTimeline AndAlso m.Success AndAlso IsTwitterId(m.Result("${ScreenName}")) Then
7239                     Me.AddNewTabForUserTimeline(m.Result("${ScreenName}"))
7240                 Else
7241                     OpenUriAsync(openUrlStr)
7242                 End If
7243                 Exit Sub
7244             End If
7245
7246             openUrlStr = openUrlStr.Replace("://twitter.com/search?q=#", "://twitter.com/search?q=%23")
7247             OpenUriAsync(openUrlStr)
7248         End If
7249     End Sub
7250
7251     Private Sub ClearTabMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ClearTabMenuItem.Click, ClearTbMenuItem.Click
7252         If String.IsNullOrEmpty(_rclickTabName) Then Exit Sub
7253         ClearTab(_rclickTabName, True)
7254     End Sub
7255
7256     Private Sub ClearTab(ByVal tabName As String, ByVal showWarning As Boolean)
7257         If showWarning Then
7258             Dim tmp As String = String.Format(My.Resources.ClearTabMenuItem_ClickText1, Environment.NewLine)
7259             If MessageBox.Show(tmp, tabName + " " + My.Resources.ClearTabMenuItem_ClickText2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
7260                 Exit Sub
7261             End If
7262         End If
7263
7264         _statuses.ClearTabIds(tabName)
7265         If ListTab.SelectedTab.Text = tabName Then
7266             _anchorPost = Nothing
7267             _anchorFlag = False
7268             _itemCache = Nothing
7269             _postCache = Nothing
7270             _itemCacheIndex = -1
7271             _curItemIndex = -1
7272             _curPost = Nothing
7273         End If
7274         For Each tb As TabPage In ListTab.TabPages
7275             If tb.Text = tabName Then
7276                 tb.ImageIndex = -1
7277                 DirectCast(tb.Tag, DetailsListView).VirtualListSize = 0
7278                 Exit For
7279             End If
7280         Next
7281         If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
7282
7283         SetMainWindowTitle()
7284         SetStatusLabelUrl()
7285     End Sub
7286
7287     Private Sub SetMainWindowTitle()
7288         'メインウインドウタイトルの書き換え
7289         Dim ttl As New StringBuilder(256)
7290         Dim ur As Integer = 0
7291         Dim al As Integer = 0
7292         Static myVer As String = fileVersion
7293         Static followers As Long = 0
7294         If SettingDialog.DispLatestPost <> DispTitleEnum.None AndAlso _
7295            SettingDialog.DispLatestPost <> DispTitleEnum.Post AndAlso _
7296            SettingDialog.DispLatestPost <> DispTitleEnum.Ver AndAlso _
7297            SettingDialog.DispLatestPost <> DispTitleEnum.OwnStatus Then
7298             For Each key As String In _statuses.Tabs.Keys
7299                 ur += _statuses.Tabs(key).UnreadCount
7300                 al += _statuses.Tabs(key).AllCount
7301             Next
7302         End If
7303
7304         If SettingDialog.DispUsername Then ttl.Append(tw.Username).Append(" - ")
7305         ttl.Append("Tween  ")
7306         Select Case SettingDialog.DispLatestPost
7307             Case DispTitleEnum.Ver
7308                 ttl.Append("Ver:").Append(myVer)
7309             Case DispTitleEnum.Post
7310                 If _history IsNot Nothing AndAlso _history.Count > 1 Then
7311                     ttl.Append(_history(_history.Count - 2).status.Replace(vbCrLf, ""))
7312                 End If
7313             Case DispTitleEnum.UnreadRepCount
7314                 ttl.AppendFormat(My.Resources.SetMainWindowTitleText1, _statuses.GetTabByType(TabUsageType.Mentions).UnreadCount + _statuses.GetTabByType(TabUsageType.DirectMessage).UnreadCount)
7315             Case DispTitleEnum.UnreadAllCount
7316                 ttl.AppendFormat(My.Resources.SetMainWindowTitleText2, ur)
7317             Case DispTitleEnum.UnreadAllRepCount
7318                 ttl.AppendFormat(My.Resources.SetMainWindowTitleText3, ur, _statuses.GetTabByType(TabUsageType.Mentions).UnreadCount + _statuses.GetTabByType(TabUsageType.DirectMessage).UnreadCount)
7319             Case DispTitleEnum.UnreadCountAllCount
7320                 ttl.AppendFormat(My.Resources.SetMainWindowTitleText4, ur, al)
7321             Case DispTitleEnum.OwnStatus
7322                 If followers = 0 AndAlso tw.FollowersCount > 0 Then followers = tw.FollowersCount
7323                 ttl.AppendFormat(My.Resources.OwnStatusTitle, tw.StatusesCount, tw.FriendsCount, tw.FollowersCount, tw.FollowersCount - followers)
7324         End Select
7325
7326         Try
7327             Me.Text = ttl.ToString()
7328         Catch ex As AccessViolationException
7329             '原因不明。ポスト内容に依存か?たまーに発生するが再現せず。
7330         End Try
7331     End Sub
7332
7333     Private Function GetStatusLabelText() As String
7334         'ステータス欄にカウント表示
7335         'タブ未読数/タブ発言数 全未読数/総発言数 (未読@+未読DM数)
7336         If _statuses Is Nothing Then Return ""
7337         Dim tbRep As TabClass = _statuses.GetTabByType(TabUsageType.Mentions)
7338         Dim tbDm As TabClass = _statuses.GetTabByType(TabUsageType.DirectMessage)
7339         If tbRep Is Nothing OrElse tbDm Is Nothing Then Return ""
7340         Dim urat As Integer = tbRep.UnreadCount + tbDm.UnreadCount
7341         Dim ur As Integer = 0
7342         Dim al As Integer = 0
7343         Dim tur As Integer = 0
7344         Dim tal As Integer = 0
7345         Dim slbl As StringBuilder = New StringBuilder(256)
7346         Try
7347             For Each key As String In _statuses.Tabs.Keys
7348                 ur += _statuses.Tabs(key).UnreadCount
7349                 al += _statuses.Tabs(key).AllCount
7350                 If key.Equals(_curTab.Text) Then
7351                     tur = _statuses.Tabs(key).UnreadCount
7352                     tal = _statuses.Tabs(key).AllCount
7353                 End If
7354             Next
7355         Catch ex As Exception
7356             Return ""
7357         End Try
7358
7359         UnreadCounter = ur
7360         UnreadAtCounter = urat
7361
7362         slbl.AppendFormat(My.Resources.SetStatusLabelText1, tur, tal, ur, al, urat, _postTimestamps.Count, _favTimestamps.Count, _tlCount)
7363         If SettingDialog.TimelinePeriodInt = 0 Then
7364             slbl.Append(My.Resources.SetStatusLabelText2)
7365         Else
7366             slbl.Append(SettingDialog.TimelinePeriodInt.ToString() + My.Resources.SetStatusLabelText3)
7367         End If
7368         Return slbl.ToString()
7369     End Function
7370
7371     Delegate Sub SetStatusLabelApiDelegate()
7372
7373     Private Sub SetStatusLabelApiHandler(ByVal sender As Object, ByVal e As ApiInformationChangedEventArgs)
7374         If InvokeRequired AndAlso Not IsDisposed Then
7375             Invoke(New SetStatusLabelApiDelegate(AddressOf SetStatusLabelApi))
7376         Else
7377             SetStatusLabelApi()
7378         End If
7379     End Sub
7380
7381     Private Sub SetStatusLabelApi()
7382         Me._apiGauge.RemainCount = TwitterApiInfo.RemainCount
7383         Me._apiGauge.MaxCount = TwitterApiInfo.MaxCount
7384         Me._apiGauge.ResetTime = TwitterApiInfo.ResetTime
7385     End Sub
7386
7387     Private Sub SetStatusLabelUrl()
7388         StatusLabelUrl.Text = GetStatusLabelText()
7389     End Sub
7390
7391     Public Sub SetStatusLabel(ByVal text As String)
7392         StatusLabel.Text = text
7393     End Sub
7394
7395     Private Sub SetNotifyIconText()
7396         ' タスクトレイアイコンのツールチップテキスト書き換え
7397         ' Tween [未読/@]
7398         Static ur As New StringBuilder(64)
7399         ur.Remove(0, ur.Length)
7400         If SettingDialog.DispUsername Then
7401             ur.Append(tw.Username)
7402             ur.Append(" - ")
7403         End If
7404         ur.Append("Tween")
7405 #If DEBUG Then
7406         ur.Append("(Debug Build)")
7407 #End If
7408         If UnreadCounter <> -1 AndAlso UnreadAtCounter <> -1 Then
7409             ur.Append(" [")
7410             ur.Append(UnreadCounter)
7411             ur.Append("/@")
7412             ur.Append(UnreadAtCounter)
7413             ur.Append("]")
7414         End If
7415         NotifyIcon1.Text = ur.ToString()
7416     End Sub
7417
7418     Friend Sub CheckReplyTo(ByVal StatusText As String)
7419         Dim m As MatchCollection
7420         'ハッシュタグの保存
7421         m = Regex.Matches(StatusText, "(^|[^a-zA-Z0-9_/])(#|#)(?<hash>[a-zA-Z0-9_]+)")
7422         Dim hstr As String = ""
7423         For Each hm As Match In m
7424             If Not IsNumeric(hm.Result("${hash}")) Then
7425                 If Not hstr.Contains("#" + hm.Result("${hash}") + " ") Then
7426                     hstr += "#" + hm.Result("${hash}") + " "
7427                     HashSupl.AddItem("#" + hm.Result("${hash}"))
7428                 End If
7429             End If
7430         Next
7431         If Not String.IsNullOrEmpty(HashMgr.UseHash) AndAlso Not hstr.Contains(HashMgr.UseHash + " ") Then
7432             hstr += HashMgr.UseHash
7433         End If
7434         If Not String.IsNullOrEmpty(hstr) Then HashMgr.AddHashToHistory(hstr.Trim, False)
7435
7436         ' 本当にリプライ先指定すべきかどうかの判定
7437         m = Regex.Matches(StatusText, "(^|[ -/:-@[-^`{-~])(?<id>@[a-zA-Z0-9_]+)")
7438
7439         If SettingDialog.UseAtIdSupplement Then
7440             Dim bCnt As Integer = AtIdSupl.ItemCount
7441             For Each mid As Match In m
7442                 AtIdSupl.AddItem(mid.Result("${id}"))
7443             Next
7444             If bCnt <> AtIdSupl.ItemCount Then _modifySettingAtId = True
7445         End If
7446
7447         ' リプライ先ステータスIDの指定がない場合は指定しない
7448         If _reply_to_id = 0 Then Exit Sub
7449
7450         ' リプライ先ユーザー名がない場合も指定しない
7451         If String.IsNullOrEmpty(_reply_to_name) Then
7452             _reply_to_id = 0
7453             Exit Sub
7454         End If
7455
7456         ' 通常Reply
7457         ' 次の条件を満たす場合に in_reply_to_status_id 指定
7458         ' 1. Twitterによりリンクと判定される @idが文中に1つ含まれる (2009/5/28 リンク化される@IDのみカウントするように修正)
7459         ' 2. リプライ先ステータスIDが設定されている(リストをダブルクリックで返信している)
7460         ' 3. 文中に含まれた@idがリプライ先のポスト者のIDと一致する
7461
7462         If m IsNot Nothing Then
7463             If StatusText.StartsWith("@") Then
7464                 If StatusText.StartsWith("@" + _reply_to_name) Then Exit Sub
7465             Else
7466                 For Each mid As Match In m
7467                     If StatusText.Contains("QT " + mid.Result("${id}") + ":") AndAlso mid.Result("${id}") = "@" + _reply_to_name Then Exit Sub
7468                 Next
7469             End If
7470         End If
7471
7472         _reply_to_id = 0
7473         _reply_to_name = ""
7474
7475     End Sub
7476
7477     Private Sub TweenMain_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Resize
7478         If Not _initialLayout AndAlso SettingDialog.MinimizeToTray AndAlso WindowState = FormWindowState.Minimized Then
7479             Me.Visible = False
7480         End If
7481         If _initialLayout AndAlso _cfgLocal IsNot Nothing AndAlso Me.WindowState = FormWindowState.Normal AndAlso Me.Visible Then
7482             Me.ClientSize = _cfgLocal.FormSize
7483             '_mySize = Me.ClientSize                     'サイズ保持(最小化・最大化されたまま終了した場合の対応用)
7484             Me.DesktopLocation = _cfgLocal.FormLocation
7485             '_myLoc = Me.DesktopLocation                        '位置保持(最小化・最大化されたまま終了した場合の対応用)
7486             If _cfgLocal.SplitterDistance > Me.SplitContainer1.Panel1MinSize AndAlso _cfgLocal.SplitterDistance < Me.SplitContainer1.Height - Me.SplitContainer1.Panel2MinSize - Me.SplitContainer1.SplitterWidth Then
7487                 Me.SplitContainer1.SplitterDistance = _cfgLocal.SplitterDistance 'Splitterの位置設定
7488             End If
7489             '発言欄複数行
7490             StatusText.Multiline = _cfgLocal.StatusMultiline
7491             If StatusText.Multiline Then
7492                 Dim dis As Integer = SplitContainer2.Height - _cfgLocal.StatusTextHeight - SplitContainer2.SplitterWidth
7493                 If dis > SplitContainer2.Panel1MinSize AndAlso dis < SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth Then
7494                     SplitContainer2.SplitterDistance = SplitContainer2.Height - _cfgLocal.StatusTextHeight - SplitContainer2.SplitterWidth
7495                 End If
7496                 StatusText.Height = _cfgLocal.StatusTextHeight
7497             Else
7498                 If SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth > 0 Then
7499                     SplitContainer2.SplitterDistance = SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth
7500                 End If
7501             End If
7502             If _cfgLocal.PreviewDistance > Me.SplitContainer3.Panel1MinSize AndAlso _cfgLocal.PreviewDistance < Me.SplitContainer3.Width - Me.SplitContainer3.Panel2MinSize - Me.SplitContainer3.SplitterWidth Then
7503                 Me.SplitContainer3.SplitterDistance = _cfgLocal.PreviewDistance
7504             End If
7505             _initialLayout = False
7506         End If
7507     End Sub
7508
7509     Private Sub PlaySoundMenuItem_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PlaySoundMenuItem.CheckedChanged, PlaySoundFileMenuItem.CheckStateChanged
7510         PlaySoundMenuItem.Checked = DirectCast(sender, ToolStripMenuItem).Checked
7511         Me.PlaySoundFileMenuItem.Checked = PlaySoundMenuItem.Checked
7512         If PlaySoundMenuItem.Checked Then
7513             SettingDialog.PlaySound = True
7514         Else
7515             SettingDialog.PlaySound = False
7516         End If
7517         _modifySettingCommon = True
7518     End Sub
7519
7520     Private Sub SplitContainer1_SplitterMoved(ByVal sender As Object, ByVal e As System.Windows.Forms.SplitterEventArgs) Handles SplitContainer1.SplitterMoved
7521         If Me.WindowState = FormWindowState.Normal AndAlso Not _initialLayout Then
7522             _mySpDis = SplitContainer1.SplitterDistance
7523             If StatusText.Multiline Then _mySpDis2 = StatusText.Height
7524             _modifySettingLocal = True
7525         End If
7526     End Sub
7527
7528     Private Sub doRepliedStatusOpen()
7529         If Me.ExistCurrentPost AndAlso _curPost.InReplyToUser IsNot Nothing AndAlso _curPost.InReplyToStatusId > 0 Then
7530             If My.Computer.Keyboard.ShiftKeyDown Then
7531                 OpenUriAsync("http://twitter.com/" + _curPost.InReplyToUser + "/status/" + _curPost.InReplyToStatusId.ToString())
7532                 Exit Sub
7533             End If
7534             If _statuses.ContainsKey(_curPost.InReplyToStatusId) Then
7535                 Dim repPost As PostClass = _statuses.Item(_curPost.InReplyToStatusId)
7536                 MessageBox.Show(repPost.ScreenName + " / " + repPost.Nickname + "   (" + repPost.CreatedAt.ToString() + ")" + Environment.NewLine + repPost.TextFromApi)
7537             Else
7538                 For Each tb As TabClass In _statuses.GetTabsByType(TabUsageType.Lists Or TabUsageType.PublicSearch)
7539                     If tb Is Nothing OrElse Not tb.Contains(_curPost.InReplyToStatusId) Then Exit For
7540                     Dim repPost As PostClass = _statuses.Item(_curPost.InReplyToStatusId)
7541                     MessageBox.Show(repPost.ScreenName + " / " + repPost.Nickname + "   (" + repPost.CreatedAt.ToString() + ")" + Environment.NewLine + repPost.TextFromApi)
7542                     Exit Sub
7543                 Next
7544                 OpenUriAsync("http://twitter.com/" + _curPost.InReplyToUser + "/status/" + _curPost.InReplyToStatusId.ToString())
7545             End If
7546         End If
7547     End Sub
7548
7549     Private Sub RepliedStatusOpenMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RepliedStatusOpenMenuItem.Click, OpenRepSourceOpMenuItem.Click
7550         doRepliedStatusOpen()
7551     End Sub
7552
7553     Private Sub ContextMenuUserPicture_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuUserPicture.Opening
7554         '発言詳細のアイコン右クリック時のメニュー制御
7555         If _curList.SelectedIndices.Count > 0 AndAlso _curPost IsNot Nothing Then
7556             Dim name As String = _curPost.ImageUrl
7557             If name IsNot Nothing AndAlso name.Length > 0 Then
7558                 Dim idx As Integer = name.LastIndexOf("/"c)
7559                 If idx <> -1 Then
7560                     name = IO.Path.GetFileName(name.Substring(idx))
7561                     If name.Contains("_normal.") Then
7562                         name = name.Replace("_normal", "")
7563                         Me.IconNameToolStripMenuItem.Text = name
7564                         Me.IconNameToolStripMenuItem.Enabled = True
7565                     Else
7566                         Me.IconNameToolStripMenuItem.Enabled = False
7567                         Me.IconNameToolStripMenuItem.Text = My.Resources.ContextMenuStrip3_OpeningText1
7568                     End If
7569                 Else
7570                     Me.IconNameToolStripMenuItem.Enabled = False
7571                     Me.IconNameToolStripMenuItem.Text = My.Resources.ContextMenuStrip3_OpeningText1
7572                 End If
7573                 If Me.TIconDic(_curPost.ImageUrl) IsNot Nothing Then
7574                     Me.SaveIconPictureToolStripMenuItem.Enabled = True
7575                 Else
7576                     Me.SaveIconPictureToolStripMenuItem.Enabled = False
7577                 End If
7578             Else
7579                 Me.IconNameToolStripMenuItem.Enabled = False
7580                 Me.SaveIconPictureToolStripMenuItem.Enabled = False
7581                 Me.IconNameToolStripMenuItem.Text = My.Resources.ContextMenuStrip3_OpeningText1
7582             End If
7583         Else
7584             Me.IconNameToolStripMenuItem.Enabled = False
7585             Me.SaveIconPictureToolStripMenuItem.Enabled = False
7586             Me.IconNameToolStripMenuItem.Text = My.Resources.ContextMenuStrip3_OpeningText2
7587         End If
7588         If NameLabel.Tag IsNot Nothing Then
7589             Dim id As String = DirectCast(NameLabel.Tag, String)
7590             If id = tw.Username Then
7591                 FollowToolStripMenuItem.Enabled = False
7592                 UnFollowToolStripMenuItem.Enabled = False
7593                 ShowFriendShipToolStripMenuItem.Enabled = False
7594                 ShowUserStatusToolStripMenuItem.Enabled = True
7595                 SearchPostsDetailNameToolStripMenuItem.Enabled = True
7596                 SearchAtPostsDetailNameToolStripMenuItem.Enabled = False
7597                 ListManageUserContextToolStripMenuItem3.Enabled = True
7598             Else
7599                 FollowToolStripMenuItem.Enabled = True
7600                 UnFollowToolStripMenuItem.Enabled = True
7601                 ShowFriendShipToolStripMenuItem.Enabled = True
7602                 ShowUserStatusToolStripMenuItem.Enabled = True
7603                 SearchPostsDetailNameToolStripMenuItem.Enabled = True
7604                 SearchAtPostsDetailNameToolStripMenuItem.Enabled = True
7605                 ListManageUserContextToolStripMenuItem3.Enabled = True
7606             End If
7607         Else
7608             FollowToolStripMenuItem.Enabled = False
7609             UnFollowToolStripMenuItem.Enabled = False
7610             ShowFriendShipToolStripMenuItem.Enabled = False
7611             ShowUserStatusToolStripMenuItem.Enabled = False
7612             SearchPostsDetailNameToolStripMenuItem.Enabled = False
7613             SearchAtPostsDetailNameToolStripMenuItem.Enabled = False
7614             ListManageUserContextToolStripMenuItem3.Enabled = False
7615         End If
7616     End Sub
7617
7618     Private Sub IconNameToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IconNameToolStripMenuItem.Click
7619         If _curPost Is Nothing Then Exit Sub
7620         Dim name As String = _curPost.ImageUrl
7621         OpenUriAsync(name.Remove(name.LastIndexOf("_normal"), 7)) ' "_normal".Length
7622     End Sub
7623
7624     Private Sub SaveOriginalSizeIconPictureToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
7625         If _curPost Is Nothing Then Exit Sub
7626         Dim name As String = _curPost.ImageUrl
7627         name = IO.Path.GetFileNameWithoutExtension(name.Substring(name.LastIndexOf("/"c)))
7628
7629         Me.SaveFileDialog1.FileName = name.Substring(0, name.Length - 8) ' "_normal".Length + 1
7630
7631         If Me.SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
7632             ' STUB
7633         End If
7634     End Sub
7635
7636     Private Sub SaveIconPictureToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveIconPictureToolStripMenuItem.Click
7637         If _curPost Is Nothing Then Exit Sub
7638         Dim name As String = _curPost.ImageUrl
7639
7640         Me.SaveFileDialog1.FileName = name.Substring(name.LastIndexOf("/"c) + 1)
7641
7642         If Me.SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
7643             Try
7644                 Using orgBmp As Image = New Bitmap(TIconDic(name))
7645                     Using bmp2 As New Bitmap(orgBmp.Size.Width, orgBmp.Size.Height)
7646                         Using g As Graphics = Graphics.FromImage(bmp2)
7647                             g.InterpolationMode = Drawing2D.InterpolationMode.High
7648                             g.DrawImage(orgBmp, 0, 0, orgBmp.Size.Width, orgBmp.Size.Height)
7649                             g.Dispose()
7650                         End Using
7651                         bmp2.Save(Me.SaveFileDialog1.FileName)
7652                         bmp2.Dispose()
7653                     End Using
7654                     orgBmp.Dispose()
7655                 End Using
7656             Catch ex As Exception
7657                 '処理中にキャッシュアウトする可能性あり
7658             End Try
7659         End If
7660     End Sub
7661
7662     Private Sub SplitContainer2_Panel2_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SplitContainer2.Panel2.Resize
7663         Me.StatusText.Multiline = Me.SplitContainer2.Panel2.Height > Me.SplitContainer2.Panel2MinSize + 2
7664         MultiLineMenuItem.Checked = Me.StatusText.Multiline
7665         _modifySettingLocal = True
7666     End Sub
7667
7668     Private Sub StatusText_MultilineChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusText.MultilineChanged
7669         If Me.StatusText.Multiline Then
7670             Me.StatusText.ScrollBars = ScrollBars.Vertical
7671         Else
7672             Me.StatusText.ScrollBars = ScrollBars.None
7673         End If
7674         _modifySettingLocal = True
7675     End Sub
7676
7677     Private Sub MultiLineMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MultiLineMenuItem.Click
7678         '発言欄複数行
7679         StatusText.Multiline = MultiLineMenuItem.Checked
7680         _cfgLocal.StatusMultiline = MultiLineMenuItem.Checked
7681         If MultiLineMenuItem.Checked Then
7682             If SplitContainer2.Height - _mySpDis2 - SplitContainer2.SplitterWidth < 0 Then
7683                 SplitContainer2.SplitterDistance = 0
7684             Else
7685                 SplitContainer2.SplitterDistance = SplitContainer2.Height - _mySpDis2 - SplitContainer2.SplitterWidth
7686             End If
7687         Else
7688             SplitContainer2.SplitterDistance = SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth
7689         End If
7690         _modifySettingLocal = True
7691     End Sub
7692
7693     Private Function UrlConvert(ByVal Converter_Type As UrlConverter) As Boolean
7694         'Converter_Type=Nicomsの場合は、nicovideoのみ短縮する
7695         '参考資料 RFC3986 Uniform Resource Identifier (URI): Generic Syntax
7696         'Appendix A.  Collected ABNF for URI
7697         'http://www.ietf.org/rfc/rfc3986.txt
7698
7699         Dim result As String = ""
7700         Const url As String = "(?<before>(?:[^\""':!=]|^|\:))" + _
7701                                    "(?<url>(?<protocol>https?://)" + _
7702                                    "(?<domain>(?:[\.-]|[^\p{P}\s])+\.[a-z]{2,}(?::[0-9]+)?)" + _
7703                                    "(?<path>/[a-z0-9!*'();:&=+$/%#\-_.,~@]*[a-z0-9)=#/]?)?" + _
7704                                    "(?<query>\?[a-z0-9!*'();:&=+$/%#\-_.,~@?]*[a-z0-9_&=#/])?)"
7705
7706         Const nico As String = "^https?://[a-z]+\.(nicovideo|niconicommons|nicolive)\.jp/[a-z]+/[a-z0-9]+$"
7707
7708         If StatusText.SelectionLength > 0 Then
7709             Dim tmp As String = StatusText.SelectedText
7710             ' httpから始まらない場合、ExcludeStringで指定された文字列で始まる場合は対象としない
7711             If tmp.StartsWith("http") Then
7712                 ' 文字列が選択されている場合はその文字列について処理
7713
7714                 'nico.ms使用、nicovideoにマッチしたら変換
7715                 If SettingDialog.Nicoms AndAlso Regex.IsMatch(tmp, nico) Then
7716                     result = nicoms.Shorten(tmp)
7717                 ElseIf Converter_Type <> UrlConverter.Nicoms Then
7718                     '短縮URL変換 日本語を含むかもしれないのでURLエンコードする
7719                     result = ShortUrl.Make(Converter_Type, tmp)
7720                     If result.Equals("Can't convert") Then
7721                         StatusLabel.Text = result.Insert(0, Converter_Type.ToString() + ":")
7722                         Return False
7723                     End If
7724                 Else
7725                     Return True
7726                 End If
7727
7728                 If Not String.IsNullOrEmpty(result) Then
7729                     Dim undotmp As New urlUndo
7730
7731                     StatusText.Select(StatusText.Text.IndexOf(tmp, StringComparison.Ordinal), tmp.Length)
7732                     StatusText.SelectedText = result
7733
7734                     'undoバッファにセット
7735                     undotmp.Before = tmp
7736                     undotmp.After = result
7737
7738                     If urlUndoBuffer Is Nothing Then
7739                         urlUndoBuffer = New List(Of urlUndo)
7740                         UrlUndoToolStripMenuItem.Enabled = True
7741                     End If
7742
7743                     urlUndoBuffer.Add(undotmp)
7744                 End If
7745             End If
7746         Else
7747             ' 正規表現にマッチしたURL文字列をtinyurl化
7748             For Each mt As Match In Regex.Matches(StatusText.Text, url, RegexOptions.IgnoreCase)
7749                 If StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal) = -1 Then Continue For
7750                 Dim tmp As String = mt.Result("${url}")
7751                 If tmp.StartsWith("w", StringComparison.OrdinalIgnoreCase) Then tmp = "http://" + tmp
7752                 Dim undotmp As New urlUndo
7753
7754                 '選んだURLを選択(?)
7755                 StatusText.Select(StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length)
7756
7757                 'nico.ms使用、nicovideoにマッチしたら変換
7758                 If SettingDialog.Nicoms AndAlso Regex.IsMatch(tmp, nico) Then
7759                     result = nicoms.Shorten(tmp)
7760                 ElseIf Converter_Type <> UrlConverter.Nicoms Then
7761                     '短縮URL変換 日本語を含むかもしれないのでURLエンコードする
7762                     result = ShortUrl.Make(Converter_Type, tmp)
7763                     If result.Equals("Can't convert") Then
7764                         StatusLabel.Text = result.Insert(0, Converter_Type.ToString() + ":")
7765                         Continue For
7766                     End If
7767                 Else
7768                     Continue For
7769                 End If
7770
7771                 If Not String.IsNullOrEmpty(result) Then
7772                     StatusText.Select(StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length)
7773                     StatusText.SelectedText = result
7774                     'undoバッファにセット
7775                     undotmp.Before = mt.Result("${url}")
7776                     undotmp.After = result
7777
7778                     If urlUndoBuffer Is Nothing Then
7779                         urlUndoBuffer = New List(Of urlUndo)
7780                         UrlUndoToolStripMenuItem.Enabled = True
7781                     End If
7782
7783                     urlUndoBuffer.Add(undotmp)
7784                 End If
7785             Next
7786         End If
7787
7788         Return True
7789
7790     End Function
7791
7792     Private Sub doUrlUndo()
7793         If urlUndoBuffer IsNot Nothing Then
7794             Dim tmp As String = StatusText.Text
7795             For Each data As urlUndo In urlUndoBuffer
7796                 tmp = tmp.Replace(data.After, data.Before)
7797             Next
7798             StatusText.Text = tmp
7799             urlUndoBuffer = Nothing
7800             UrlUndoToolStripMenuItem.Enabled = False
7801         End If
7802     End Sub
7803
7804     Private Sub TinyURLToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TinyURLToolStripMenuItem.Click
7805         UrlConvert(UrlConverter.TinyUrl)
7806     End Sub
7807
7808     Private Sub IsgdToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IsgdToolStripMenuItem.Click
7809         UrlConvert(UrlConverter.Isgd)
7810     End Sub
7811
7812     Private Sub TwurlnlToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TwurlnlToolStripMenuItem.Click
7813         UrlConvert(UrlConverter.Twurl)
7814     End Sub
7815
7816     Private Sub UxnuMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UxnuMenuItem.Click
7817         UrlConvert(UrlConverter.Uxnu)
7818     End Sub
7819
7820     Private Sub UrlConvertAutoToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UrlConvertAutoToolStripMenuItem.Click
7821         If Not UrlConvert(SettingDialog.AutoShortUrlFirst) Then
7822             Dim svc As UrlConverter = SettingDialog.AutoShortUrlFirst
7823             Dim rnd As New Random()
7824             ' 前回使用した短縮URLサービス以外を選択する
7825             Do
7826                 svc = CType(rnd.Next(System.Enum.GetNames(GetType(UrlConverter)).Length), UrlConverter)
7827             Loop Until svc <> SettingDialog.AutoShortUrlFirst AndAlso svc <> UrlConverter.Nicoms AndAlso svc <> UrlConverter.Unu
7828             UrlConvert(svc)
7829         End If
7830     End Sub
7831
7832     Private Sub UrlUndoToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UrlUndoToolStripMenuItem.Click
7833         doUrlUndo()
7834     End Sub
7835
7836     Private Sub NewPostPopMenuItem_CheckStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles NewPostPopMenuItem.CheckStateChanged, NotifyFileMenuItem.CheckStateChanged
7837         Me.NotifyFileMenuItem.Checked = DirectCast(sender, ToolStripMenuItem).Checked
7838         Me.NewPostPopMenuItem.Checked = Me.NotifyFileMenuItem.Checked
7839         _cfgCommon.NewAllPop = NewPostPopMenuItem.Checked
7840         _modifySettingCommon = True
7841     End Sub
7842
7843     Private Sub ListLockMenuItem_CheckStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListLockMenuItem.CheckStateChanged, LockListFileMenuItem.CheckStateChanged
7844         ListLockMenuItem.Checked = DirectCast(sender, ToolStripMenuItem).Checked
7845         Me.LockListFileMenuItem.Checked = ListLockMenuItem.Checked
7846         _cfgCommon.ListLock = ListLockMenuItem.Checked
7847         _modifySettingCommon = True
7848     End Sub
7849
7850     Private Sub MenuStrip1_MenuActivate(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuStrip1.MenuActivate
7851         ' フォーカスがメニューに移る (MenuStrip1.Tag フラグを立てる)
7852         MenuStrip1.Tag = New Object()
7853         MenuStrip1.Select() ' StatusText がフォーカスを持っている場合 Leave が発生
7854     End Sub
7855
7856     Private Sub MenuStrip1_MenuDeactivate(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuStrip1.MenuDeactivate
7857         If Me.Tag IsNot Nothing Then ' 設定された戻り先へ遷移
7858             If Me.Tag Is Me.ListTab.SelectedTab Then
7859                 DirectCast(Me.ListTab.SelectedTab.Tag, Control).Select()
7860             Else
7861                 DirectCast(Me.Tag, Control).Select()
7862             End If
7863         Else ' 戻り先が指定されていない (初期状態) 場合はタブに遷移
7864             If ListTab.SelectedIndex > -1 AndAlso ListTab.SelectedTab.HasChildren Then
7865                 Me.Tag = ListTab.SelectedTab.Tag
7866                 DirectCast(Me.Tag, Control).Select()
7867             End If
7868         End If
7869         ' フォーカスがメニューに遷移したかどうかを表すフラグを降ろす
7870         MenuStrip1.Tag = Nothing
7871     End Sub
7872
7873     Private Sub MyList_ColumnReordered(ByVal sender As System.Object, ByVal e As ColumnReorderedEventArgs)
7874         Dim lst As DetailsListView = DirectCast(sender, DetailsListView)
7875         If _cfgLocal Is Nothing Then Exit Sub
7876
7877         If _iconCol Then
7878             _cfgLocal.Width1 = lst.Columns(0).Width
7879             _cfgLocal.Width3 = lst.Columns(1).Width
7880         Else
7881             Dim darr(lst.Columns.Count - 1) As Integer
7882             For i As Integer = 0 To lst.Columns.Count - 1
7883                 darr(lst.Columns(i).DisplayIndex) = i
7884             Next
7885             MoveArrayItem(darr, e.OldDisplayIndex, e.NewDisplayIndex)
7886
7887             For i As Integer = 0 To lst.Columns.Count - 1
7888                 Select Case darr(i)
7889                     Case 0
7890                         _cfgLocal.DisplayIndex1 = i
7891                     Case 1
7892                         _cfgLocal.DisplayIndex2 = i
7893                     Case 2
7894                         _cfgLocal.DisplayIndex3 = i
7895                     Case 3
7896                         _cfgLocal.DisplayIndex4 = i
7897                     Case 4
7898                         _cfgLocal.DisplayIndex5 = i
7899                     Case 5
7900                         _cfgLocal.DisplayIndex6 = i
7901                     Case 6
7902                         _cfgLocal.DisplayIndex7 = i
7903                     Case 7
7904                         _cfgLocal.DisplayIndex8 = i
7905                 End Select
7906             Next
7907             _cfgLocal.Width1 = lst.Columns(0).Width
7908             _cfgLocal.Width2 = lst.Columns(1).Width
7909             _cfgLocal.Width3 = lst.Columns(2).Width
7910             _cfgLocal.Width4 = lst.Columns(3).Width
7911             _cfgLocal.Width5 = lst.Columns(4).Width
7912             _cfgLocal.Width6 = lst.Columns(5).Width
7913             _cfgLocal.Width7 = lst.Columns(6).Width
7914             _cfgLocal.Width8 = lst.Columns(7).Width
7915         End If
7916         _modifySettingLocal = True
7917         _isColumnChanged = True
7918     End Sub
7919
7920     Private Sub MyList_ColumnWidthChanged(ByVal sender As System.Object, ByVal e As ColumnWidthChangedEventArgs)
7921         Dim lst As DetailsListView = DirectCast(sender, DetailsListView)
7922         If _cfgLocal Is Nothing Then Exit Sub
7923         If _iconCol Then
7924             If _cfgLocal.Width1 <> lst.Columns(0).Width Then
7925                 _cfgLocal.Width1 = lst.Columns(0).Width
7926                 _modifySettingLocal = True
7927                 _isColumnChanged = True
7928             End If
7929             If _cfgLocal.Width3 <> lst.Columns(1).Width Then
7930                 _cfgLocal.Width3 = lst.Columns(1).Width
7931                 _modifySettingLocal = True
7932                 _isColumnChanged = True
7933             End If
7934         Else
7935             If _cfgLocal.Width1 <> lst.Columns(0).Width Then
7936                 _cfgLocal.Width1 = lst.Columns(0).Width
7937                 _modifySettingLocal = True
7938                 _isColumnChanged = True
7939             End If
7940             If _cfgLocal.Width2 <> lst.Columns(1).Width Then
7941                 _cfgLocal.Width2 = lst.Columns(1).Width
7942                 _modifySettingLocal = True
7943                 _isColumnChanged = True
7944             End If
7945             If _cfgLocal.Width3 <> lst.Columns(2).Width Then
7946                 _cfgLocal.Width3 = lst.Columns(2).Width
7947                 _modifySettingLocal = True
7948                 _isColumnChanged = True
7949             End If
7950             If _cfgLocal.Width4 <> lst.Columns(3).Width Then
7951                 _cfgLocal.Width4 = lst.Columns(3).Width
7952                 _modifySettingLocal = True
7953                 _isColumnChanged = True
7954             End If
7955             If _cfgLocal.Width5 <> lst.Columns(4).Width Then
7956                 _cfgLocal.Width5 = lst.Columns(4).Width
7957                 _modifySettingLocal = True
7958                 _isColumnChanged = True
7959             End If
7960             If _cfgLocal.Width6 <> lst.Columns(5).Width Then
7961                 _cfgLocal.Width6 = lst.Columns(5).Width
7962                 _modifySettingLocal = True
7963                 _isColumnChanged = True
7964             End If
7965             If _cfgLocal.Width7 <> lst.Columns(6).Width Then
7966                 _cfgLocal.Width7 = lst.Columns(6).Width
7967                 _modifySettingLocal = True
7968                 _isColumnChanged = True
7969             End If
7970             If _cfgLocal.Width8 <> lst.Columns(7).Width Then
7971                 _cfgLocal.Width8 = lst.Columns(7).Width
7972                 _modifySettingLocal = True
7973                 _isColumnChanged = True
7974             End If
7975         End If
7976         ' 非表示の時にColumnChangedが呼ばれた場合はForm初期化処理中なので保存しない
7977         'If changed Then
7978         '    SaveConfigsLocal()
7979         'End If
7980     End Sub
7981
7982     Public Function WebBrowser_GetSelectionText(ByRef ComponentInstance As WebBrowser) As String
7983         '発言詳細で「選択文字列をコピー」を行う
7984         'WebBrowserコンポーネントのインスタンスを渡す
7985         Dim typ As Type = ComponentInstance.ActiveXInstance.GetType()
7986         Dim _SelObj As Object = typ.InvokeMember("selection", BindingFlags.GetProperty, Nothing, ComponentInstance.Document.DomDocument, Nothing)
7987         Dim _objRange As Object = _SelObj.GetType().InvokeMember("createRange", BindingFlags.InvokeMethod, Nothing, _SelObj, Nothing)
7988         Return DirectCast(_objRange.GetType().InvokeMember("text", BindingFlags.GetProperty, Nothing, _objRange, Nothing), String)
7989     End Function
7990
7991     Private Sub SelectionCopyContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectionCopyContextMenuItem.Click
7992         '発言詳細で「選択文字列をコピー」
7993         Dim _selText As String = WebBrowser_GetSelectionText(PostBrowser)
7994         Try
7995             Clipboard.SetDataObject(_selText, False, 5, 100)
7996         Catch ex As Exception
7997             MessageBox.Show(ex.Message)
7998         End Try
7999     End Sub
8000
8001     Private Sub doSearchToolStrip(ByVal url As String)
8002         '発言詳細で「選択文字列で検索」(選択文字列取得)
8003         Dim _selText As String = WebBrowser_GetSelectionText(PostBrowser)
8004
8005         If _selText IsNot Nothing Then
8006             If url = My.Resources.SearchItem4Url Then
8007                 '公式検索
8008                 AddNewTabForSearch(_selText)
8009                 Exit Sub
8010             End If
8011
8012             Dim tmp As String = String.Format(url, HttpUtility.UrlEncode(_selText))
8013             OpenUriAsync(tmp)
8014         End If
8015     End Sub
8016
8017     Private Sub SelectionAllContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectionAllContextMenuItem.Click
8018         '発言詳細ですべて選択
8019         PostBrowser.Document.ExecCommand("SelectAll", False, Nothing)
8020     End Sub
8021
8022     Private Sub SearchWikipediaContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchWikipediaContextMenuItem.Click
8023         doSearchToolStrip(My.Resources.SearchItem1Url)
8024     End Sub
8025
8026     Private Sub SearchGoogleContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchGoogleContextMenuItem.Click
8027         doSearchToolStrip(My.Resources.SearchItem2Url)
8028     End Sub
8029
8030     Private Sub SearchYatsContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchYatsContextMenuItem.Click
8031         doSearchToolStrip(My.Resources.SearchItem3Url)
8032     End Sub
8033
8034     Private Sub SearchPublicSearchContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchPublicSearchContextMenuItem.Click
8035         doSearchToolStrip(My.Resources.SearchItem4Url)
8036     End Sub
8037
8038     Private Sub UrlCopyContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UrlCopyContextMenuItem.Click
8039         Try
8040             Clipboard.SetDataObject(Me._postBrowserStatusText, False, 5, 100)
8041         Catch ex As Exception
8042             MessageBox.Show(ex.Message)
8043         End Try
8044     End Sub
8045
8046     Private Sub ContextMenuPostBrowser_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuPostBrowser.Opening
8047         ' URLコピーの項目の表示/非表示
8048         If PostBrowser.StatusText.StartsWith("http") Then
8049             Me._postBrowserStatusText = PostBrowser.StatusText
8050             Dim name As String = GetUserId()
8051             UrlCopyContextMenuItem.Enabled = True
8052             If name IsNot Nothing Then
8053                 FollowContextMenuItem.Enabled = True
8054                 RemoveContextMenuItem.Enabled = True
8055                 FriendshipContextMenuItem.Enabled = True
8056                 ShowUserStatusContextMenuItem.Enabled = True
8057                 SearchPostsDetailToolStripMenuItem.Enabled = True
8058                 IdFilterAddMenuItem.Enabled = True
8059                 ListManageUserContextToolStripMenuItem.Enabled = True
8060                 SearchAtPostsDetailToolStripMenuItem.Enabled = True
8061             Else
8062                 FollowContextMenuItem.Enabled = False
8063                 RemoveContextMenuItem.Enabled = False
8064                 FriendshipContextMenuItem.Enabled = False
8065                 ShowUserStatusContextMenuItem.Enabled = False
8066                 SearchPostsDetailToolStripMenuItem.Enabled = False
8067                 IdFilterAddMenuItem.Enabled = False
8068                 ListManageUserContextToolStripMenuItem.Enabled = False
8069                 SearchAtPostsDetailToolStripMenuItem.Enabled = False
8070             End If
8071
8072             If Regex.IsMatch(Me._postBrowserStatusText, "^https?://twitter.com/search\?q=%23") Then
8073                 UseHashtagMenuItem.Enabled = True
8074             Else
8075                 UseHashtagMenuItem.Enabled = False
8076             End If
8077         Else
8078             Me._postBrowserStatusText = ""
8079             UrlCopyContextMenuItem.Enabled = False
8080             FollowContextMenuItem.Enabled = False
8081             RemoveContextMenuItem.Enabled = False
8082             FriendshipContextMenuItem.Enabled = False
8083             ShowUserStatusContextMenuItem.Enabled = False
8084             SearchPostsDetailToolStripMenuItem.Enabled = False
8085             SearchAtPostsDetailToolStripMenuItem.Enabled = False
8086             UseHashtagMenuItem.Enabled = False
8087             IdFilterAddMenuItem.Enabled = False
8088             ListManageUserContextToolStripMenuItem.Enabled = False
8089         End If
8090         ' 文字列選択されていないときは選択文字列関係の項目を非表示に
8091         Dim _selText As String = WebBrowser_GetSelectionText(PostBrowser)
8092         If _selText Is Nothing Then
8093             SelectionSearchContextMenuItem.Enabled = False
8094             SelectionCopyContextMenuItem.Enabled = False
8095             SelectionTranslationToolStripMenuItem.Enabled = False
8096         Else
8097             SelectionSearchContextMenuItem.Enabled = True
8098             SelectionCopyContextMenuItem.Enabled = True
8099             SelectionTranslationToolStripMenuItem.Enabled = True
8100         End If
8101         '発言内に自分以外のユーザーが含まれてればフォロー状態全表示を有効に
8102         Dim ma As MatchCollection = Regex.Matches(Me.PostBrowser.DocumentText, "href=""https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?""")
8103         Dim fAllFlag As Boolean = False
8104         For Each mu As Match In ma
8105             If mu.Result("${ScreenName}").ToLower <> tw.Username.ToLower Then
8106                 fAllFlag = True
8107                 Exit For
8108             End If
8109         Next
8110         Me.FriendshipAllMenuItem.Enabled = fAllFlag
8111
8112         If _curPost Is Nothing Then
8113             TranslationToolStripMenuItem.Enabled = False
8114         Else
8115             TranslationToolStripMenuItem.Enabled = True
8116         End If
8117
8118         e.Cancel = False
8119     End Sub
8120
8121     Private Sub CurrentTabToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CurrentTabToolStripMenuItem.Click
8122         '発言詳細の選択文字列で現在のタブを検索
8123         Dim _selText As String = WebBrowser_GetSelectionText(PostBrowser)
8124
8125         If _selText IsNot Nothing Then
8126             SearchDialog.SWord = _selText
8127             SearchDialog.CheckCaseSensitive = False
8128             SearchDialog.CheckRegex = False
8129
8130             DoTabSearch(SearchDialog.SWord, _
8131                         SearchDialog.CheckCaseSensitive, _
8132                         SearchDialog.CheckRegex, _
8133                         SEARCHTYPE.NextSearch)
8134         End If
8135     End Sub
8136
8137     Private Sub SplitContainer2_SplitterMoved(ByVal sender As Object, ByVal e As System.Windows.Forms.SplitterEventArgs) Handles SplitContainer2.SplitterMoved
8138         If StatusText.Multiline Then _mySpDis2 = StatusText.Height
8139         _modifySettingLocal = True
8140     End Sub
8141
8142     Private Sub TweenMain_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragDrop
8143         If e.Data.GetDataPresent(DataFormats.FileDrop) Then
8144             ImageSelectionPanel.Visible = True
8145             ImageSelectionPanel.Enabled = True
8146             TimelinePanel.Visible = False
8147             TimelinePanel.Enabled = False
8148             ImagefilePathText.Text = CType(e.Data.GetData(DataFormats.FileDrop, False), String())(0)
8149             ImageFromSelectedFile()
8150             Me.Activate()
8151             StatusText.Focus()
8152         ElseIf e.Data.GetDataPresent(DataFormats.StringFormat) Then
8153             Dim data As String = TryCast(e.Data.GetData(DataFormats.StringFormat, True), String)
8154             If data IsNot Nothing Then StatusText.Text += data
8155         End If
8156     End Sub
8157
8158     Private Sub TweenMain_DragOver(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragOver
8159         If e.Data.GetDataPresent(DataFormats.FileDrop) Then
8160             Dim filename As String = CType(e.Data.GetData(DataFormats.FileDrop, False), String())(0)
8161             Dim fl As New FileInfo(filename)
8162             Dim ext As String = fl.Extension
8163
8164             If Not String.IsNullOrEmpty(Me.ImageService) AndAlso Me.pictureService(Me.ImageService).CheckValidFilesize(ext, fl.Length) Then
8165                 e.Effect = DragDropEffects.Copy
8166                 Exit Sub
8167             End If
8168             For Each svc As String In ImageServiceCombo.Items
8169                 If String.IsNullOrEmpty(svc) Then Continue For
8170                 If Me.pictureService(svc).CheckValidFilesize(ext, fl.Length) Then
8171                     ImageServiceCombo.SelectedItem = svc
8172                     e.Effect = DragDropEffects.Copy
8173                     Exit Sub
8174                 End If
8175             Next
8176             e.Effect = DragDropEffects.None
8177         ElseIf e.Data.GetDataPresent(DataFormats.StringFormat) Then
8178             e.Effect = DragDropEffects.Copy
8179         Else
8180             e.Effect = DragDropEffects.None
8181         End If
8182     End Sub
8183
8184     Public Function IsNetworkAvailable() As Boolean
8185         Dim nw As Boolean = True
8186         Try
8187             nw = My.Computer.Network.IsAvailable
8188         Catch ex As Exception
8189             nw = False
8190         End Try
8191         _myStatusOnline = nw
8192         Return nw
8193     End Function
8194
8195     Public Sub OpenUriAsync(ByVal UriString As String)
8196         Dim args As New GetWorkerArg
8197         args.type = WORKERTYPE.OpenUri
8198         args.url = UriString
8199
8200         RunAsync(args)
8201     End Sub
8202
8203     Private Sub ListTabSelect(ByVal _tab As TabPage)
8204         SetListProperty()
8205
8206         _itemCache = Nothing
8207         _itemCacheIndex = -1
8208         _postCache = Nothing
8209
8210         _curTab = _tab
8211         _curList = DirectCast(_tab.Tag, DetailsListView)
8212         If _curList.SelectedIndices.Count > 0 Then
8213             _curItemIndex = _curList.SelectedIndices(0)
8214             _curPost = GetCurTabPost(_curItemIndex)
8215         Else
8216             _curItemIndex = -1
8217             _curPost = Nothing
8218         End If
8219
8220         _anchorPost = Nothing
8221         _anchorFlag = False
8222
8223         If _iconCol Then
8224             DirectCast(_tab.Tag, DetailsListView).Columns.Item(1).Text = ColumnText(2)
8225         Else
8226             For i As Integer = 0 To _curList.Columns.Count - 1
8227                 DirectCast(_tab.Tag, DetailsListView).Columns.Item(i).Text = ColumnText(i)
8228             Next
8229         End If
8230     End Sub
8231
8232     Private Sub ListTab_Selecting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TabControlCancelEventArgs) Handles ListTab.Selecting
8233         ListTabSelect(e.TabPage)
8234     End Sub
8235
8236     Private Sub SelectListItem(ByVal LView As DetailsListView, ByVal Index As Integer)
8237         '単一
8238         Dim bnd As Rectangle
8239         Dim flg As Boolean = False
8240         If LView.FocusedItem IsNot Nothing Then
8241             bnd = LView.FocusedItem.Bounds
8242             flg = True
8243         End If
8244
8245         Do
8246             LView.SelectedIndices.Clear()
8247         Loop While LView.SelectedIndices.Count > 0
8248         LView.Items(Index).Selected = True
8249         'LView.SelectedIndices.Add(Index)
8250         LView.Items(Index).Focused = True
8251
8252         If flg Then LView.Invalidate(bnd)
8253     End Sub
8254
8255     Private Sub SelectListItem(ByVal LView As DetailsListView, ByVal Index() As Integer, ByVal FocusedIndex As Integer)
8256         '複数
8257         Dim bnd As Rectangle
8258         Dim flg As Boolean = False
8259         If LView.FocusedItem IsNot Nothing Then
8260             bnd = LView.FocusedItem.Bounds
8261             flg = True
8262         End If
8263
8264         Dim fIdx As Integer = -1
8265         If Index IsNot Nothing AndAlso Not (Index.Count = 1 AndAlso Index(0) = -1) Then
8266             Do
8267                 LView.SelectedIndices.Clear()
8268             Loop While LView.SelectedIndices.Count > 0
8269             For Each idx As Integer In Index
8270                 If idx > -1 AndAlso LView.VirtualListSize > idx Then
8271                     LView.SelectedIndices.Add(idx)
8272                     If fIdx = -1 Then fIdx = idx
8273                 End If
8274             Next
8275         End If
8276         If FocusedIndex > -1 AndAlso LView.VirtualListSize > FocusedIndex Then
8277             LView.Items(FocusedIndex).Focused = True
8278         ElseIf fIdx > -1 Then
8279             LView.Items(fIdx).Focused = True
8280         End If
8281         If flg Then LView.Invalidate(bnd)
8282     End Sub
8283
8284     Private Sub RunAsync(ByVal args As GetWorkerArg)
8285         Dim bw As BackgroundWorker = Nothing
8286         If args.type <> WORKERTYPE.Follower Then
8287             For i As Integer = 0 To _bw.Length - 1
8288                 If _bw(i) IsNot Nothing AndAlso Not _bw(i).IsBusy Then
8289                     bw = _bw(i)
8290                     Exit For
8291                 End If
8292             Next
8293             If bw Is Nothing Then
8294                 For i As Integer = 0 To _bw.Length - 1
8295                     If _bw(i) Is Nothing Then
8296                         _bw(i) = New BackgroundWorker
8297                         bw = _bw(i)
8298                         bw.WorkerReportsProgress = True
8299                         bw.WorkerSupportsCancellation = True
8300                         AddHandler bw.DoWork, AddressOf GetTimelineWorker_DoWork
8301                         AddHandler bw.ProgressChanged, AddressOf GetTimelineWorker_ProgressChanged
8302                         AddHandler bw.RunWorkerCompleted, AddressOf GetTimelineWorker_RunWorkerCompleted
8303                         Exit For
8304                     End If
8305                 Next
8306             End If
8307         Else
8308             If _bwFollower Is Nothing Then
8309                 _bwFollower = New BackgroundWorker
8310                 bw = _bwFollower
8311                 bw.WorkerReportsProgress = True
8312                 bw.WorkerSupportsCancellation = True
8313                 AddHandler bw.DoWork, AddressOf GetTimelineWorker_DoWork
8314                 AddHandler bw.ProgressChanged, AddressOf GetTimelineWorker_ProgressChanged
8315                 AddHandler bw.RunWorkerCompleted, AddressOf GetTimelineWorker_RunWorkerCompleted
8316             Else
8317                 If _bwFollower.IsBusy = False Then
8318                     bw = _bwFollower
8319                 End If
8320             End If
8321         End If
8322         If bw Is Nothing Then Exit Sub
8323
8324         bw.RunWorkerAsync(args)
8325     End Sub
8326
8327     Private Sub StartUserStream()
8328         AddHandler tw.NewPostFromStream, AddressOf tw_NewPostFromStream
8329         AddHandler tw.UserStreamStarted, AddressOf tw_UserStreamStarted
8330         AddHandler tw.UserStreamStopped, AddressOf tw_UserStreamStopped
8331         AddHandler tw.PostDeleted, AddressOf tw_PostDeleted
8332         AddHandler tw.UserStreamEventReceived, AddressOf tw_UserStreamEventArrived
8333
8334         MenuItemUserStream.Text = "&UserStream ■"
8335         MenuItemUserStream.Enabled = True
8336         StopToolStripMenuItem.Text = "&Start"
8337         StopToolStripMenuItem.Enabled = True
8338         If SettingDialog.UserstreamStartup Then tw.StartUserStream()
8339     End Sub
8340
8341     Private Sub TweenMain_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
8342         Try
8343             PostBrowser.Url = New Uri("about:blank")
8344             PostBrowser.DocumentText = ""       '発言詳細部初期化
8345         Catch ex As Exception
8346
8347         End Try
8348
8349         NotifyIcon1.Visible = True
8350
8351         If IsNetworkAvailable() Then
8352             If SettingDialog.StartupFollowers Then
8353                 GetTimeline(WORKERTYPE.Follower, 0, 0, "")
8354             End If
8355             StartUserStream()
8356             _waitTimeline = True
8357             GetTimeline(WORKERTYPE.Timeline, 1, 1, "")
8358             _waitReply = True
8359             GetTimeline(WORKERTYPE.Reply, 1, 1, "")
8360             _waitDm = True
8361             GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 1, "")
8362             If SettingDialog.GetFav Then
8363                 _waitFav = True
8364                 GetTimeline(WORKERTYPE.Favorites, 1, 1, "")
8365             End If
8366             _waitPubSearch = True
8367             GetTimeline(WORKERTYPE.PublicSearch, 1, 0, "")  'tabname="":全タブ
8368             _waitUserTimeline = True
8369             GetTimeline(WORKERTYPE.UserTimeline, 1, 0, "")  'tabname="":全タブ
8370             _waitLists = True
8371             GetTimeline(WORKERTYPE.List, 1, 0, "")  'tabname="":全タブ
8372             Dim i As Integer = 0
8373             Dim j As Integer = 0
8374             Do While (IsInitialRead()) AndAlso Not _endingFlag
8375                 System.Threading.Thread.Sleep(100)
8376                 My.Application.DoEvents()
8377                 i += 1
8378                 j += 1
8379                 If j > 1200 Then Exit Do ' 120秒間初期処理が終了しなかったら強制的に打ち切る
8380                 If i > 50 Then
8381                     If _endingFlag Then
8382                         Exit Sub
8383                     End If
8384                     i = 0
8385                 End If
8386             Loop
8387
8388             If _endingFlag Then Exit Sub
8389
8390             'バージョンチェック(引数:起動時チェックの場合はTrue・・・チェック結果のメッセージを表示しない)
8391             If SettingDialog.StartupVersion Then
8392                 CheckNewVersion(True)
8393             End If
8394
8395             ' 取得失敗の場合は再試行する
8396             If Not tw.GetFollowersSuccess AndAlso SettingDialog.StartupFollowers Then
8397                 GetTimeline(WORKERTYPE.Follower, 0, 0, "")
8398             End If
8399         End If
8400         _initial = False
8401
8402         TimerTimeline.Enabled = True
8403     End Sub
8404
8405     Private Function IsInitialRead() As Boolean
8406         Return _waitTimeline OrElse _waitReply OrElse _waitDm OrElse _waitFav OrElse _waitPubSearch OrElse _waitUserTimeline OrElse _waitLists
8407     End Function
8408
8409     Private Sub doGetFollowersMenu()
8410         GetTimeline(WORKERTYPE.Follower, 1, 0, "")
8411         DispSelectedPost(True)
8412     End Sub
8413
8414     Private Sub GetFollowersAllToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UpdateFollowersMenuItem1.Click
8415         doGetFollowersMenu()
8416     End Sub
8417
8418     Private Sub doReTweetUnofficial()
8419         'RT @id:内容
8420         If Me.ExistCurrentPost Then
8421             If _curPost.IsDm OrElse _
8422                Not StatusText.Enabled Then Exit Sub
8423
8424             If _curPost.IsProtect Then
8425                 MessageBox.Show("Protected.")
8426                 Exit Sub
8427             End If
8428             Dim rtdata As String = _curPost.Text
8429             rtdata = CreateRetweetUnofficial(rtdata)
8430
8431             StatusText.Text = "RT @" + _curPost.ScreenName + ": " + HttpUtility.HtmlDecode(rtdata)
8432
8433             StatusText.SelectionStart = 0
8434             StatusText.Focus()
8435         End If
8436     End Sub
8437
8438     Private Sub ReTweetStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReTweetStripMenuItem.Click, RtUnOpMenuItem.Click
8439         doReTweetUnofficial()
8440     End Sub
8441
8442     Private Sub doReTweetOfficial(ByVal isConfirm As Boolean)
8443         '公式RT
8444         If Me.ExistCurrentPost Then
8445             If _curPost.IsProtect Then
8446                 MessageBox.Show("Protected.")
8447                 _DoFavRetweetFlags = False
8448                 Exit Sub
8449             End If
8450             If _curList.SelectedIndices.Count > 15 Then
8451                 MessageBox.Show(My.Resources.RetweetLimitText)
8452                 _DoFavRetweetFlags = False
8453                 Exit Sub
8454             ElseIf _curList.SelectedIndices.Count > 1 Then
8455                 Dim QuestionText As String = My.Resources.RetweetQuestion2
8456                 If _DoFavRetweetFlags Then QuestionText = My.Resources.FavoriteRetweetQuestionText1
8457                 Select Case MessageBox.Show(QuestionText, "Retweet", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)
8458                     Case Windows.Forms.DialogResult.Cancel, Windows.Forms.DialogResult.No
8459                         _DoFavRetweetFlags = False
8460                         Exit Sub
8461                 End Select
8462             Else
8463                 If _curPost.IsDm OrElse _curPost.IsMe Then
8464                     _DoFavRetweetFlags = False
8465                     Exit Sub
8466                 End If
8467                 If Not SettingDialog.RetweetNoConfirm Then
8468                     Dim Questiontext As String = My.Resources.RetweetQuestion1
8469                     If _DoFavRetweetFlags Then Questiontext = My.Resources.FavoritesRetweetQuestionText2
8470                     If isConfirm AndAlso MessageBox.Show(Questiontext, "Retweet", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
8471                         _DoFavRetweetFlags = False
8472                         Exit Sub
8473                     End If
8474                 End If
8475             End If
8476             Dim args As New GetWorkerArg
8477             args.ids = New List(Of Long)
8478             args.sIds = New List(Of Long)
8479             args.tName = _curTab.Text
8480             args.type = WORKERTYPE.Retweet
8481             For Each idx As Integer In _curList.SelectedIndices
8482                 Dim post As PostClass = GetCurTabPost(idx)
8483                 If Not post.IsMe AndAlso Not post.IsProtect AndAlso Not post.IsDm Then args.ids.Add(post.StatusId)
8484             Next
8485             RunAsync(args)
8486         End If
8487     End Sub
8488
8489     Private Sub ReTweetOriginalStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReTweetOriginalStripMenuItem.Click, RtOpMenuItem.Click
8490         doReTweetOfficial(True)
8491     End Sub
8492
8493     Private Sub FavoritesRetweetOriginal()
8494         If Not Me.ExistCurrentPost Then Exit Sub
8495         _DoFavRetweetFlags = True
8496         doReTweetOfficial(True)
8497         If _DoFavRetweetFlags Then
8498             _DoFavRetweetFlags = False
8499             FavoriteChange(True, False)
8500         End If
8501     End Sub
8502
8503     Private Sub FavoritesRetweetUnofficial()
8504         If Me.ExistCurrentPost AndAlso Not _curPost.IsDm Then
8505             _DoFavRetweetFlags = True
8506             FavoriteChange(True)
8507             If Not _curPost.IsProtect AndAlso _DoFavRetweetFlags Then
8508                 _DoFavRetweetFlags = False
8509                 doReTweetUnofficial()
8510             End If
8511         End If
8512     End Sub
8513
8514     Private Function CreateRetweetUnofficial(ByVal status As String) As String
8515
8516         ' Twitterにより省略されているURLを含むaタグをキャプチャしてリンク先URLへ置き換える
8517         '展開しないように変更
8518         '展開するか判定
8519         Dim isUrl As Boolean = False
8520         Dim ms As MatchCollection = Regex.Matches(status, "<a target=""_self"" href=""(?<url>[^""]+)""[^>]*>(?<link>(https?|shttp|ftps?)://[^<]+)</a>")
8521         For Each m As Match In ms
8522             If m.Result("${link}").EndsWith("...") Then
8523                 isUrl = True
8524                 Exit For
8525             End If
8526         Next
8527         If isUrl Then
8528             status = Regex.Replace(status, "<a target=""_self"" href=""(?<url>[^""]+)""[^>]*>(?<link>(https?|shttp|ftps?)://[^<]+)</a>", "${url}")
8529         Else
8530             status = Regex.Replace(status, "<a target=""_self"" href=""(?<url>[^""]+)""[^>]*>(?<link>(https?|shttp|ftps?)://[^<]+)</a>", "${link}")
8531         End If
8532
8533         'その他のリンク(@IDなど)を置き換える
8534         status = Regex.Replace(status, "@<a target=""_self"" href=""https?://twitter.com/(#!/)?(?<url>[^""]+)""[^>]*>(?<link>[^<]+)</a>", "@${url}")
8535         'ハッシュタグ
8536         status = Regex.Replace(status, "<a target=""_self"" href=""(?<url>[^""]+)""[^>]*>(?<link>[^<]+)</a>", "${link}")
8537         '<br>タグ除去
8538         If StatusText.Multiline Then
8539             status = Regex.Replace(status, "(\r\n|\n|\r)?<br>", vbCrLf, RegexOptions.IgnoreCase Or RegexOptions.Multiline)
8540         Else
8541             status = Regex.Replace(status, "(\r\n|\n|\r)?<br>", "", RegexOptions.IgnoreCase Or RegexOptions.Multiline)
8542         End If
8543
8544         _reply_to_id = 0
8545         _reply_to_name = ""
8546         status = status.Replace("&nbsp;", " ")
8547
8548         Return status
8549     End Function
8550
8551     Private Sub DumpPostClassToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DumpPostClassToolStripMenuItem.Click
8552         If _curPost IsNot Nothing Then
8553             DispSelectedPost(True)
8554         End If
8555     End Sub
8556
8557     Private Sub MenuItemHelp_DropDownOpening(ByVal sender As Object, ByVal e As System.EventArgs) Handles MenuItemHelp.DropDownOpening
8558         If DebugBuild OrElse My.Computer.Keyboard.CapsLock AndAlso My.Computer.Keyboard.CtrlKeyDown AndAlso My.Computer.Keyboard.ShiftKeyDown Then
8559             DebugModeToolStripMenuItem.Visible = True
8560         Else
8561             DebugModeToolStripMenuItem.Visible = False
8562         End If
8563     End Sub
8564
8565     Private Sub ToolStripMenuItemUrlAutoShorten_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItemUrlAutoShorten.CheckedChanged
8566         SettingDialog.UrlConvertAuto = ToolStripMenuItemUrlAutoShorten.Checked
8567     End Sub
8568
8569     Private Sub ContextMenuPostMode_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuPostMode.Opening
8570         ToolStripMenuItemUrlAutoShorten.Checked = SettingDialog.UrlConvertAuto
8571     End Sub
8572
8573     Private Sub TraceOutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TraceOutToolStripMenuItem.Click
8574         If TraceOutToolStripMenuItem.Checked Then
8575             TraceFlag = True
8576         Else
8577             TraceFlag = False
8578         End If
8579     End Sub
8580
8581     Private Sub TweenMain_Deactivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Deactivate
8582         '画面が非アクティブになったら、発言欄の背景色をデフォルトへ
8583         Me.StatusText_Leave(StatusText, System.EventArgs.Empty)
8584     End Sub
8585
8586     Private Sub TabRenameMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TabRenameMenuItem.Click, RenameTbMenuItem.Click
8587         If String.IsNullOrEmpty(_rclickTabName) Then Exit Sub
8588         TabRename(_rclickTabName)
8589     End Sub
8590
8591     Private Sub BitlyToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BitlyToolStripMenuItem.Click
8592         UrlConvert(UrlConverter.Bitly)
8593     End Sub
8594
8595     Private Sub JmpToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles JmpStripMenuItem.Click
8596         UrlConvert(UrlConverter.Jmp)
8597     End Sub
8598
8599
8600     Private Class GetApiInfoArgs
8601         Public tw As Twitter
8602         Public info As ApiInfo
8603     End Class
8604
8605     Private Sub GetApiInfo_Dowork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
8606         Dim args As GetApiInfoArgs = DirectCast(e.Argument, GetApiInfoArgs)
8607         e.Result = tw.GetInfoApi(args.info)
8608     End Sub
8609
8610     Private Sub ApiInfoMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ApiInfoMenuItem.Click
8611         Dim info As New ApiInfo
8612         Dim tmp As String
8613         Dim args As New GetApiInfoArgs With {.tw = tw, .info = info}
8614
8615         Using dlg As New FormInfo(Me, My.Resources.ApiInfo6, AddressOf GetApiInfo_Dowork, Nothing, args)
8616             dlg.ShowDialog()
8617             If CBool(dlg.Result) Then
8618                 tmp = My.Resources.ApiInfo1 + args.info.MaxCount.ToString() + Environment.NewLine + _
8619                     My.Resources.ApiInfo2 + args.info.RemainCount.ToString() + Environment.NewLine + _
8620                     My.Resources.ApiInfo3 + args.info.ResetTime.ToString() + Environment.NewLine + _
8621                     My.Resources.ApiInfo7 + IIf(tw.UserStreamEnabled, My.Resources.Enable, My.Resources.Disable).ToString()
8622                 SetStatusLabelUrl()
8623             Else
8624                 tmp = My.Resources.ApiInfo5
8625             End If
8626         End Using
8627
8628         MessageBox.Show(tmp, My.Resources.ApiInfo4, MessageBoxButtons.OK, MessageBoxIcon.Information)
8629     End Sub
8630
8631     Private Sub FollowCommandMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FollowCommandMenuItem.Click
8632         Dim id As String = ""
8633         If _curPost IsNot Nothing Then id = _curPost.ScreenName
8634         FollowCommand(id)
8635     End Sub
8636
8637     Private Sub FollowCommand_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
8638         Dim arg As FollowRemoveCommandArgs = DirectCast(e.Argument, FollowRemoveCommandArgs)
8639         e.Result = arg.tw.PostFollowCommand(arg.id)
8640     End Sub
8641
8642     Private Sub FollowCommand(ByVal id As String)
8643         Using inputName As New InputTabName()
8644             inputName.FormTitle = "Follow"
8645             inputName.FormDescription = My.Resources.FRMessage1
8646             inputName.TabName = id
8647             If inputName.ShowDialog() = Windows.Forms.DialogResult.OK AndAlso _
8648                Not String.IsNullOrEmpty(inputName.TabName.Trim()) Then
8649                 Dim arg As New FollowRemoveCommandArgs
8650                 arg.tw = tw
8651                 arg.id = inputName.TabName.Trim()
8652                 Using _info As New FormInfo(Me, My.Resources.FollowCommandText1, _
8653                                             AddressOf FollowCommand_DoWork, _
8654                                             Nothing, _
8655                                             arg)
8656                     _info.ShowDialog()
8657                     Dim ret As String = DirectCast(_info.Result, String)
8658                     If Not String.IsNullOrEmpty(ret) Then
8659                         MessageBox.Show(My.Resources.FRMessage2 + ret)
8660                     Else
8661                         MessageBox.Show(My.Resources.FRMessage3)
8662                     End If
8663                 End Using
8664             End If
8665         End Using
8666     End Sub
8667
8668     Private Sub RemoveCommandMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RemoveCommandMenuItem.Click
8669         Dim id As String = ""
8670         If _curPost IsNot Nothing Then id = _curPost.ScreenName
8671         RemoveCommand(id, False)
8672     End Sub
8673
8674     Private Class FollowRemoveCommandArgs
8675         Public tw As Tween.Twitter
8676         Public id As String
8677     End Class
8678
8679     Private Sub RemoveCommand_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
8680         Dim arg As FollowRemoveCommandArgs = DirectCast(e.Argument, FollowRemoveCommandArgs)
8681         e.Result = arg.tw.PostRemoveCommand(arg.id)
8682     End Sub
8683
8684     Private Sub RemoveCommand(ByVal id As String, ByVal skipInput As Boolean)
8685         Dim arg As New FollowRemoveCommandArgs
8686         arg.tw = tw
8687         arg.id = id
8688         If Not skipInput Then
8689             Using inputName As New InputTabName()
8690                 inputName.FormTitle = "Unfollow"
8691                 inputName.FormDescription = My.Resources.FRMessage1
8692                 inputName.TabName = id
8693                 If inputName.ShowDialog() = Windows.Forms.DialogResult.OK AndAlso _
8694                    Not String.IsNullOrEmpty(inputName.TabName.Trim()) Then
8695                     arg.tw = tw
8696                     arg.id = inputName.TabName.Trim()
8697                 Else
8698                     Exit Sub
8699                 End If
8700             End Using
8701         End If
8702
8703         Using _info As New FormInfo(Me, My.Resources.RemoveCommandText1, _
8704                                     AddressOf RemoveCommand_DoWork, _
8705                                     Nothing, _
8706                                     arg)
8707             _info.ShowDialog()
8708             Dim ret As String = DirectCast(_info.Result, String)
8709             If Not String.IsNullOrEmpty(ret) Then
8710                 MessageBox.Show(My.Resources.FRMessage2 + ret)
8711             Else
8712                 MessageBox.Show(My.Resources.FRMessage3)
8713             End If
8714         End Using
8715     End Sub
8716
8717     Private Sub FriendshipMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FriendshipMenuItem.Click
8718         Dim id As String = ""
8719         If _curPost IsNot Nothing Then
8720             id = _curPost.ScreenName
8721         End If
8722         ShowFriendship(id)
8723     End Sub
8724
8725     Private Class ShowFriendshipArgs
8726         Public tw As Tween.Twitter
8727         Public Class FriendshipInfo
8728             Public id As String = ""
8729             Public isFollowing As Boolean = False
8730             Public isFollowed As Boolean = False
8731             Public isError As Boolean = False
8732             Public Sub New(ByVal id As String)
8733                 Me.id = id
8734             End Sub
8735         End Class
8736         Public ids As New List(Of FriendshipInfo)
8737     End Class
8738
8739     Private Sub ShowFriendship_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
8740         Dim arg As ShowFriendshipArgs = DirectCast(e.Argument, ShowFriendshipArgs)
8741         Dim result As String = ""
8742         For Each fInfo As ShowFriendshipArgs.FriendshipInfo In arg.ids
8743             Dim rt As String = arg.tw.GetFriendshipInfo(fInfo.id, fInfo.isFollowing, fInfo.isFollowed)
8744             If Not String.IsNullOrEmpty(rt) Then
8745                 If String.IsNullOrEmpty(result) Then result = rt
8746                 fInfo.isError = True
8747             End If
8748         Next
8749         e.Result = result
8750     End Sub
8751
8752     Private Sub ShowFriendship(ByVal id As String)
8753         Dim args As New ShowFriendshipArgs
8754         args.tw = tw
8755         Using inputName As New InputTabName()
8756             inputName.FormTitle = "Show Friendships"
8757             inputName.FormDescription = My.Resources.FRMessage1
8758             inputName.TabName = id
8759             If inputName.ShowDialog() = Windows.Forms.DialogResult.OK AndAlso _
8760                Not String.IsNullOrEmpty(inputName.TabName.Trim()) Then
8761                 Dim ret As String = ""
8762                 args.ids.Add(New ShowFriendshipArgs.FriendshipInfo(inputName.TabName.Trim))
8763                 Using _info As New FormInfo(Me, My.Resources.ShowFriendshipText1, _
8764                                             AddressOf ShowFriendship_DoWork, _
8765                                             Nothing, _
8766                                             args)
8767                     _info.ShowDialog()
8768                     ret = DirectCast(_info.Result, String)
8769                 End Using
8770                 Dim result As String = ""
8771                 If String.IsNullOrEmpty(ret) Then
8772                     If args.ids(0).isFollowing Then
8773                         result = My.Resources.GetFriendshipInfo1 + System.Environment.NewLine
8774                     Else
8775                         result = My.Resources.GetFriendshipInfo2 + System.Environment.NewLine
8776                     End If
8777                     If args.ids(0).isFollowed Then
8778                         result += My.Resources.GetFriendshipInfo3
8779                     Else
8780                         result += My.Resources.GetFriendshipInfo4
8781                     End If
8782                     result = args.ids(0).id + My.Resources.GetFriendshipInfo5 + System.Environment.NewLine + result
8783                 Else
8784                     result = ret
8785                 End If
8786                 MessageBox.Show(result)
8787             End If
8788         End Using
8789     End Sub
8790
8791     Private Sub ShowFriendship(ByVal ids() As String)
8792         For Each id As String In ids
8793             Dim ret As String = ""
8794             Dim args As New ShowFriendshipArgs
8795             args.tw = tw
8796             args.ids.Add(New ShowFriendshipArgs.FriendshipInfo(id.Trim))
8797             Using _info As New FormInfo(Me, My.Resources.ShowFriendshipText1, _
8798                                         AddressOf ShowFriendship_DoWork, _
8799                                         Nothing, _
8800                                         args)
8801                 _info.ShowDialog()
8802                 ret = DirectCast(_info.Result, String)
8803             End Using
8804             Dim result As String = ""
8805             Dim fInfo As ShowFriendshipArgs.FriendshipInfo = args.ids(0)
8806             Dim ff As String = ""
8807             If String.IsNullOrEmpty(ret) Then
8808                 ff = "  "
8809                 If fInfo.isFollowing Then
8810                     ff += My.Resources.GetFriendshipInfo1
8811                 Else
8812                     ff += My.Resources.GetFriendshipInfo2
8813                 End If
8814                 ff += System.Environment.NewLine + "  "
8815                 If fInfo.isFollowed Then
8816                     ff += My.Resources.GetFriendshipInfo3
8817                 Else
8818                     ff += My.Resources.GetFriendshipInfo4
8819                 End If
8820                 result += fInfo.id + My.Resources.GetFriendshipInfo5 + System.Environment.NewLine + ff
8821                 If fInfo.isFollowing Then
8822                     If MessageBox.Show( _
8823                         My.Resources.GetFriendshipInfo7 + System.Environment.NewLine + result, My.Resources.GetFriendshipInfo8, _
8824                         MessageBoxButtons.YesNo, _
8825                         MessageBoxIcon.Question, _
8826                         MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.Yes Then
8827                         RemoveCommand(fInfo.id, True)
8828                     End If
8829                 Else
8830                     MessageBox.Show(result)
8831                 End If
8832             Else
8833                 MessageBox.Show(ret)
8834             End If
8835         Next
8836     End Sub
8837
8838     Private Sub OwnStatusMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OwnStatusMenuItem.Click
8839         doShowUserStatus(tw.Username, False)
8840         'If Not String.IsNullOrEmpty(tw.UserInfoXml) Then
8841         '    doShowUserStatus(tw.Username, False)
8842         'Else
8843         '    MessageBox.Show(My.Resources.ShowYourProfileText1, "Your status", MessageBoxButtons.OK, MessageBoxIcon.Information)
8844         '    Exit Sub
8845         'End If
8846     End Sub
8847
8848     ' TwitterIDでない固定文字列を調べる(文字列検証のみ 実際に取得はしない)
8849     ' URLから切り出した文字列を渡す
8850
8851     Public Function IsTwitterId(ByVal name As String) As Boolean
8852         Return Not Regex.Match(name, "^(about|jobs|tos|privacy)$").Success
8853     End Function
8854
8855     Private Function GetUserId() As String
8856         Dim m As Match = Regex.Match(Me._postBrowserStatusText, "^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?$")
8857         If m.Success AndAlso IsTwitterId(m.Result("${ScreenName}")) Then
8858             Return m.Result("${ScreenName}")
8859         Else
8860             Return Nothing
8861         End If
8862     End Function
8863
8864     Private Sub FollowContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FollowContextMenuItem.Click
8865         Dim name As String = GetUserId()
8866         If name IsNot Nothing Then FollowCommand(name)
8867     End Sub
8868
8869     Private Sub RemoveContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RemoveContextMenuItem.Click
8870         Dim name As String = GetUserId()
8871         If name IsNot Nothing Then RemoveCommand(name, False)
8872     End Sub
8873
8874     Private Sub FriendshipContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FriendshipContextMenuItem.Click
8875         Dim name As String = GetUserId()
8876         If name IsNot Nothing Then ShowFriendship(name)
8877     End Sub
8878
8879     Private Sub FriendshipAllMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FriendshipAllMenuItem.Click
8880         Dim ma As MatchCollection = Regex.Matches(Me.PostBrowser.DocumentText, "href=""https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?""")
8881         Dim ids As New List(Of String)
8882         For Each mu As Match In ma
8883             If mu.Result("${ScreenName}").ToLower <> tw.Username.ToLower Then
8884                 ids.Add(mu.Result("${ScreenName}"))
8885             End If
8886         Next
8887         ShowFriendship(ids.ToArray)
8888     End Sub
8889
8890     Private Sub ShowUserStatusContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ShowUserStatusContextMenuItem.Click
8891         Dim name As String = GetUserId()
8892         If name IsNot Nothing Then ShowUserStatus(name)
8893     End Sub
8894
8895     Private Sub SearchPostsDetailToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchPostsDetailToolStripMenuItem.Click
8896         Dim name As String = GetUserId()
8897         If name IsNot Nothing Then AddNewTabForUserTimeline(name)
8898     End Sub
8899
8900     Private Sub SearchAtPostsDetailToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchAtPostsDetailToolStripMenuItem.Click
8901         Dim name As String = GetUserId()
8902         If name IsNot Nothing Then AddNewTabForSearch("@" + name)
8903     End Sub
8904
8905     Private Sub IdeographicSpaceToSpaceToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IdeographicSpaceToSpaceToolStripMenuItem.Click
8906         _modifySettingCommon = True
8907     End Sub
8908
8909     Private Sub ToolStripFocusLockMenuItem_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripFocusLockMenuItem.Click
8910         _modifySettingCommon = True
8911     End Sub
8912
8913     Private Sub doQuote()
8914         'QT @id:内容
8915         '返信先情報付加
8916         If Me.ExistCurrentPost Then
8917             If _curPost.IsDm OrElse _
8918                Not StatusText.Enabled Then Exit Sub
8919
8920             If _curPost.IsProtect Then
8921                 MessageBox.Show("Protected.")
8922                 Exit Sub
8923             End If
8924             Dim rtdata As String = _curPost.Text
8925             rtdata = CreateRetweetUnofficial(rtdata)
8926
8927             StatusText.Text = " QT @" + _curPost.ScreenName + ": " + HttpUtility.HtmlDecode(rtdata)
8928             If _curPost.RetweetedId = 0 Then
8929                 _reply_to_id = _curPost.StatusId
8930             Else
8931                 _reply_to_id = _curPost.RetweetedId
8932             End If
8933             _reply_to_name = _curPost.ScreenName
8934
8935             StatusText.SelectionStart = 0
8936             StatusText.Focus()
8937         End If
8938     End Sub
8939
8940     Private Sub QuoteStripMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles QuoteStripMenuItem.Click, QtOpMenuItem.Click
8941         doQuote()
8942     End Sub
8943
8944     Private Sub SearchButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
8945         '公式検索
8946         Dim pnl As Control = DirectCast(sender, Control).Parent
8947         If pnl Is Nothing Then Exit Sub
8948         Dim tbName As String = pnl.Parent.Text
8949         Dim tb As TabClass = _statuses.Tabs(tbName)
8950         Dim cmb As ComboBox = DirectCast(pnl.Controls("comboSearch"), ComboBox)
8951         Dim cmbLang As ComboBox = DirectCast(pnl.Controls("comboLang"), ComboBox)
8952         Dim cmbusline As ComboBox = DirectCast(pnl.Controls("comboUserline"), ComboBox)
8953         cmb.Text = cmb.Text.Trim
8954         ' 検索式演算子 OR についてのみ大文字しか認識しないので強制的に大文字とする
8955         Dim Quote As Boolean = False
8956         Dim buf As New StringBuilder()
8957         Dim c As Char() = cmb.Text.ToCharArray()
8958         For cnt As Integer = 0 To cmb.Text.Length - 1
8959             If cnt > cmb.Text.Length - 4 Then
8960                 buf.Append(cmb.Text.Substring(cnt))
8961                 Exit For
8962             End If
8963             If c(cnt) = CChar("""") Then
8964                 Quote = Not Quote
8965             Else
8966                 If Not Quote AndAlso cmb.Text.Substring(cnt, 4).Equals(" or ", StringComparison.OrdinalIgnoreCase) Then
8967                     buf.Append(" OR ")
8968                     cnt += 3
8969                     Continue For
8970                 End If
8971             End If
8972             buf.Append(c(cnt))
8973         Next
8974         cmb.Text = buf.ToString()
8975
8976         tb.SearchWords = cmb.Text
8977         tb.SearchLang = cmbLang.Text
8978         If cmb.Text = "" Then
8979             DirectCast(ListTab.SelectedTab.Tag, DetailsListView).Focus()
8980             SaveConfigsTabs()
8981             Exit Sub
8982         End If
8983         If tb.IsQueryChanged Then
8984             Dim idx As Integer = DirectCast(pnl.Controls("comboSearch"), ComboBox).Items.IndexOf(tb.SearchWords)
8985             If idx > -1 Then DirectCast(pnl.Controls("comboSearch"), ComboBox).Items.RemoveAt(idx)
8986             DirectCast(pnl.Controls("comboSearch"), ComboBox).Items.Insert(0, tb.SearchWords)
8987             cmb.Text = tb.SearchWords
8988             cmb.SelectAll()
8989             Dim lst As DetailsListView = DirectCast(pnl.Parent.Tag, DetailsListView)
8990             lst.VirtualListSize = 0
8991             lst.Items.Clear()
8992             _statuses.ClearTabIds(tbName)
8993             SaveConfigsTabs()   '検索条件の保存
8994         End If
8995
8996         GetTimeline(WORKERTYPE.PublicSearch, 1, 0, tbName)
8997         DirectCast(ListTab.SelectedTab.Tag, DetailsListView).Focus()
8998     End Sub
8999
9000     Private Sub RefreshMoreStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RefreshMoreStripMenuItem.Click, RefreshPrevOpMenuItem.Click
9001         'もっと前を取得
9002         DoRefreshMore()
9003     End Sub
9004
9005     Private Sub UndoRemoveTabMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UndoRemoveTabMenuItem.Click
9006         If _statuses.RemovedTab.Count = 0 Then
9007             MessageBox.Show("There isn't removed tab.", "Undo", MessageBoxButtons.OK, MessageBoxIcon.Information)
9008             Exit Sub
9009         Else
9010             Dim tb As TabClass = _statuses.RemovedTab.Pop()
9011             Dim renamed As String = tb.TabName
9012             For i As Integer = 1 To Integer.MaxValue
9013                 If Not _statuses.ContainsTab(renamed) Then Exit For
9014                 renamed = tb.TabName + "(" + i.ToString + ")"
9015             Next
9016             tb.TabName = renamed
9017             _statuses.Tabs.Add(renamed, tb)
9018             AddNewTab(renamed, False, tb.TabType, tb.ListInfo)
9019             ListTab.SelectedIndex = ListTab.TabPages.Count - 1
9020             SaveConfigsTabs()
9021         End If
9022     End Sub
9023
9024     Private Sub doMoveToRTHome()
9025         If _curList.SelectedIndices.Count > 0 Then
9026             Dim post As PostClass = GetCurTabPost(_curList.SelectedIndices(0))
9027             If post.RetweetedId > 0 Then
9028                 OpenUriAsync("http://twitter.com/" + GetCurTabPost(_curList.SelectedIndices(0)).RetweetedBy)
9029             End If
9030         End If
9031     End Sub
9032
9033     Private Sub MoveToRTHomeMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MoveToRTHomeMenuItem.Click, OpenRterHomeMenuItem.Click
9034         doMoveToRTHome()
9035     End Sub
9036
9037     Private Sub IdFilterAddMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IdFilterAddMenuItem.Click
9038         Dim name As String = GetUserId()
9039         If name IsNot Nothing Then
9040             Dim tabName As String = ""
9041
9042             '未選択なら処理終了
9043             If _curList.SelectedIndices.Count = 0 Then Exit Sub
9044
9045             'タブ選択(or追加)
9046             If Not SelectTab(tabName) Then Exit Sub
9047
9048             Dim mv As Boolean = False
9049             Dim mk As Boolean = False
9050             MoveOrCopy(mv, mk)
9051
9052             Dim fc As New FiltersClass
9053             fc.NameFilter = name
9054             fc.SearchBoth = True
9055             fc.MoveFrom = mv
9056             fc.SetMark = mk
9057             fc.UseRegex = False
9058             fc.SearchUrl = False
9059             _statuses.Tabs(tabName).AddFilter(fc)
9060
9061             Try
9062                 Me.Cursor = Cursors.WaitCursor
9063                 _itemCache = Nothing
9064                 _postCache = Nothing
9065                 _curPost = Nothing
9066                 _curItemIndex = -1
9067                 _statuses.FilterAll()
9068                 For Each tb As TabPage In ListTab.TabPages
9069                     DirectCast(tb.Tag, DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
9070                     If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
9071                         If SettingDialog.TabIconDisp Then
9072                             tb.ImageIndex = 0
9073                         End If
9074                     Else
9075                         If SettingDialog.TabIconDisp Then
9076                             tb.ImageIndex = -1
9077                         End If
9078                     End If
9079                 Next
9080                 If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
9081             Finally
9082                 Me.Cursor = Cursors.Default
9083             End Try
9084             SaveConfigsTabs()
9085         End If
9086     End Sub
9087
9088     Private Sub ListManageUserContextToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListManageUserContextToolStripMenuItem.Click, ListManageMenuItem.Click, ListManageUserContextToolStripMenuItem2.Click, ListManageUserContextToolStripMenuItem3.Click
9089         Dim user As String
9090
9091         Dim menuItem As ToolStripMenuItem = DirectCast(sender, ToolStripMenuItem)
9092
9093         If menuItem.Owner Is Me.ContextMenuPostBrowser Then
9094             user = GetUserId()
9095             If user Is Nothing Then Return
9096         ElseIf Me._curPost IsNot Nothing Then
9097             user = Me._curPost.ScreenName
9098         Else
9099             Return
9100         End If
9101
9102         Dim list As ListElement = Nothing
9103
9104         If TabInformations.GetInstance().SubscribableLists.Count = 0 Then
9105             Dim res As String = Me.tw.GetListsApi()
9106
9107             If res <> "" Then
9108                 MessageBox.Show("Failed to get lists. (" + res + ")")
9109                 Return
9110             End If
9111         End If
9112
9113         Using listSelectForm As New MyLists(user, Me.tw)
9114             listSelectForm.ShowDialog(Me)
9115         End Using
9116     End Sub
9117
9118     Private Sub SearchControls_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs)
9119         Dim pnl As Control = DirectCast(sender, Control)
9120         For Each ctl As Control In pnl.Controls
9121             ctl.TabStop = True
9122         Next
9123     End Sub
9124
9125     Private Sub SearchControls_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs)
9126         Dim pnl As Control = DirectCast(sender, Control)
9127         For Each ctl As Control In pnl.Controls
9128             ctl.TabStop = False
9129         Next
9130     End Sub
9131
9132     Private Sub PublicSearchQueryMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PublicSearchQueryMenuItem.Click
9133         If ListTab.SelectedTab IsNot Nothing Then
9134             If _statuses.Tabs(ListTab.SelectedTab.Text).TabType <> TabUsageType.PublicSearch Then Exit Sub
9135             ListTab.SelectedTab.Controls("panelSearch").Controls("comboSearch").Focus()
9136         End If
9137     End Sub
9138
9139     Private Sub UseHashtagMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UseHashtagMenuItem.Click
9140         Dim m As Match = Regex.Match(Me._postBrowserStatusText, "^https?://twitter.com/search\?q=%23(?<hash>[a-zA-Z0-9_]+)$")
9141         If m.Success Then
9142             HashMgr.SetPermanentHash("#" + m.Result("${hash}"))
9143             HashStripSplitButton.Text = HashMgr.UseHash
9144             HashToggleMenuItem.Checked = True
9145             HashToggleToolStripMenuItem.Checked = True
9146             '使用ハッシュタグとして設定
9147             _modifySettingCommon = True
9148         End If
9149     End Sub
9150
9151     Private Sub StatusLabel_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusLabel.DoubleClick
9152         MessageBox.Show(StatusLabel.TextHistory, "Logs", MessageBoxButtons.OK, MessageBoxIcon.None)
9153     End Sub
9154
9155     Private Sub HashManageMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles HashManageMenuItem.Click, HashManageToolStripMenuItem.Click
9156         Dim rslt As DialogResult
9157         Try
9158             rslt = HashMgr.ShowDialog()
9159         Catch ex As Exception
9160             Exit Sub
9161         End Try
9162         Me.TopMost = SettingDialog.AlwaysTop
9163         If rslt = Windows.Forms.DialogResult.Cancel Then Exit Sub
9164         If HashMgr.UseHash <> "" Then
9165             HashStripSplitButton.Text = HashMgr.UseHash
9166             HashToggleMenuItem.Checked = True
9167             HashToggleToolStripMenuItem.Checked = True
9168         Else
9169             HashStripSplitButton.Text = "#[-]"
9170             HashToggleMenuItem.Checked = False
9171             HashToggleToolStripMenuItem.Checked = False
9172         End If
9173         'If HashMgr.IsInsert AndAlso HashMgr.UseHash <> "" Then
9174         '    Dim sidx As Integer = StatusText.SelectionStart
9175         '    Dim hash As String = HashMgr.UseHash + " "
9176         '    If sidx > 0 Then
9177         '        If StatusText.Text.Substring(sidx - 1, 1) <> " " Then
9178         '            hash = " " + hash
9179         '        End If
9180         '    End If
9181         '    StatusText.Text = StatusText.Text.Insert(sidx, hash)
9182         '    sidx += hash.Length
9183         '    StatusText.SelectionStart = sidx
9184         '    StatusText.Focus()
9185         'End If
9186         _modifySettingCommon = True
9187         Me.StatusText_TextChanged(Nothing, Nothing)
9188     End Sub
9189
9190     Private Sub HashToggleMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles HashToggleMenuItem.Click, HashToggleToolStripMenuItem.Click
9191         HashMgr.ToggleHash()
9192         If HashMgr.UseHash <> "" Then
9193             HashStripSplitButton.Text = HashMgr.UseHash
9194             HashToggleMenuItem.Checked = True
9195             HashToggleToolStripMenuItem.Checked = True
9196         Else
9197             HashStripSplitButton.Text = "#[-]"
9198             HashToggleMenuItem.Checked = False
9199             HashToggleToolStripMenuItem.Checked = False
9200         End If
9201         _modifySettingCommon = True
9202         Me.StatusText_TextChanged(Nothing, Nothing)
9203     End Sub
9204
9205     Private Sub HashStripSplitButton_ButtonClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles HashStripSplitButton.ButtonClick
9206         HashToggleMenuItem_Click(Nothing, Nothing)
9207     End Sub
9208
9209     Private Sub MenuItemOperate_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemOperate.DropDownOpening
9210         If ListTab.SelectedTab Is Nothing Then Exit Sub
9211         If _statuses Is Nothing OrElse _statuses.Tabs Is Nothing OrElse Not _statuses.Tabs.ContainsKey(ListTab.SelectedTab.Text) Then Exit Sub
9212         If Not Me.ExistCurrentPost Then
9213             Me.ReplyOpMenuItem.Enabled = False
9214             Me.ReplyAllOpMenuItem.Enabled = False
9215             Me.DmOpMenuItem.Enabled = False
9216             Me.ShowProfMenuItem.Enabled = False
9217             Me.ShowUserTimelineToolStripMenuItem.Enabled = False
9218             Me.ListManageMenuItem.Enabled = False
9219             Me.OpenFavOpMenuItem.Enabled = False
9220             Me.CreateTabRuleOpMenuItem.Enabled = False
9221             Me.CreateIdRuleOpMenuItem.Enabled = False
9222             Me.ReadOpMenuItem.Enabled = False
9223             Me.UnreadOpMenuItem.Enabled = False
9224         Else
9225             Me.ReplyOpMenuItem.Enabled = True
9226             Me.ReplyAllOpMenuItem.Enabled = True
9227             Me.DmOpMenuItem.Enabled = True
9228             Me.ShowProfMenuItem.Enabled = True
9229             Me.ShowUserTimelineToolStripMenuItem.Enabled = True
9230             Me.ListManageMenuItem.Enabled = True
9231             Me.OpenFavOpMenuItem.Enabled = True
9232             Me.CreateTabRuleOpMenuItem.Enabled = True
9233             Me.CreateIdRuleOpMenuItem.Enabled = True
9234             Me.ReadOpMenuItem.Enabled = True
9235             Me.UnreadOpMenuItem.Enabled = True
9236         End If
9237
9238         If _statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.DirectMessage OrElse Not Me.ExistCurrentPost OrElse _curPost.IsDm Then
9239             Me.FavOpMenuItem.Enabled = False
9240             Me.UnFavOpMenuItem.Enabled = False
9241             Me.OpenStatusOpMenuItem.Enabled = False
9242             Me.OpenFavotterOpMenuItem.Enabled = False
9243             Me.ShowRelatedStatusesMenuItem2.Enabled = False
9244             Me.RtOpMenuItem.Enabled = False
9245             Me.RtUnOpMenuItem.Enabled = False
9246             Me.QtOpMenuItem.Enabled = False
9247             Me.FavoriteRetweetMenuItem.Enabled = False
9248             Me.FavoriteRetweetUnofficialMenuItem.Enabled = False
9249             If Me.ExistCurrentPost AndAlso _curPost.IsDm Then Me.DelOpMenuItem.Enabled = True
9250         Else
9251             Me.FavOpMenuItem.Enabled = True
9252             Me.UnFavOpMenuItem.Enabled = True
9253             Me.OpenStatusOpMenuItem.Enabled = True
9254             Me.OpenFavotterOpMenuItem.Enabled = True
9255             Me.ShowRelatedStatusesMenuItem2.Enabled = True  'PublicSearchの時問題出るかも
9256
9257             If _curPost.IsMe Then
9258                 Me.RtOpMenuItem.Enabled = False
9259                 Me.FavoriteRetweetMenuItem.Enabled = False
9260                 Me.DelOpMenuItem.Enabled = True
9261             Else
9262                 Me.DelOpMenuItem.Enabled = False
9263                 If _curPost.IsProtect Then
9264                     Me.RtOpMenuItem.Enabled = False
9265                     Me.RtUnOpMenuItem.Enabled = False
9266                     Me.QtOpMenuItem.Enabled = False
9267                     Me.FavoriteRetweetMenuItem.Enabled = False
9268                     Me.FavoriteRetweetUnofficialMenuItem.Enabled = False
9269                 Else
9270                     Me.RtOpMenuItem.Enabled = True
9271                     Me.RtUnOpMenuItem.Enabled = True
9272                     Me.QtOpMenuItem.Enabled = True
9273                     Me.FavoriteRetweetMenuItem.Enabled = True
9274                     Me.FavoriteRetweetUnofficialMenuItem.Enabled = True
9275                 End If
9276             End If
9277         End If
9278
9279         If _statuses.Tabs(ListTab.SelectedTab.Text).TabType <> TabUsageType.Favorites Then
9280             Me.RefreshPrevOpMenuItem.Enabled = True
9281         Else
9282             Me.RefreshPrevOpMenuItem.Enabled = False
9283         End If
9284         If _statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.PublicSearch _
9285                             OrElse Not Me.ExistCurrentPost _
9286                             OrElse Not _curPost.InReplyToStatusId > 0 Then
9287             OpenRepSourceOpMenuItem.Enabled = False
9288         Else
9289             OpenRepSourceOpMenuItem.Enabled = True
9290         End If
9291         If Not Me.ExistCurrentPost OrElse _curPost.RetweetedBy = "" Then
9292             OpenRterHomeMenuItem.Enabled = False
9293         Else
9294             OpenRterHomeMenuItem.Enabled = True
9295         End If
9296     End Sub
9297
9298     Private Sub MenuItemTab_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemTab.DropDownOpening
9299         ContextMenuTabProperty_Opening(sender, Nothing)
9300     End Sub
9301
9302     Public ReadOnly Property TwitterInstance() As Twitter
9303         Get
9304             Return tw
9305         End Get
9306     End Property
9307
9308
9309     Private Sub SplitContainer3_SplitterMoved(ByVal sender As System.Object, ByVal e As System.Windows.Forms.SplitterEventArgs) Handles SplitContainer3.SplitterMoved
9310         If Me.WindowState = FormWindowState.Normal AndAlso Not _initialLayout Then
9311             _mySpDis3 = SplitContainer3.SplitterDistance
9312             _modifySettingLocal = True
9313         End If
9314     End Sub
9315
9316     Private Sub MenuItemEdit_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemEdit.DropDownOpening
9317         If _statuses.RemovedTab.Count = 0 Then
9318             UndoRemoveTabMenuItem.Enabled = False
9319         Else
9320             UndoRemoveTabMenuItem.Enabled = True
9321         End If
9322         If ListTab.SelectedTab IsNot Nothing Then
9323             If _statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.PublicSearch Then
9324                 PublicSearchQueryMenuItem.Enabled = True
9325             Else
9326                 PublicSearchQueryMenuItem.Enabled = False
9327             End If
9328         Else
9329             PublicSearchQueryMenuItem.Enabled = False
9330         End If
9331         If Not Me.ExistCurrentPost Then
9332             Me.CopySTOTMenuItem.Enabled = False
9333             Me.CopyURLMenuItem.Enabled = False
9334             Me.CopyUserIdStripMenuItem.Enabled = False
9335         Else
9336             Me.CopySTOTMenuItem.Enabled = True
9337             Me.CopyURLMenuItem.Enabled = True
9338             Me.CopyUserIdStripMenuItem.Enabled = True
9339             If _curPost.IsDm Then Me.CopyURLMenuItem.Enabled = False
9340             If _curPost.IsProtect Then Me.CopySTOTMenuItem.Enabled = False
9341         End If
9342     End Sub
9343
9344     Private Sub NotifyIcon1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.MouseMove
9345         SetNotifyIconText()
9346     End Sub
9347
9348     Private Sub UserStatusToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UserStatusToolStripMenuItem.Click
9349         Dim id As String = ""
9350         If _curPost IsNot Nothing Then
9351             id = _curPost.ScreenName
9352         End If
9353         ShowUserStatus(id)
9354     End Sub
9355
9356     Private Class GetUserInfoArgs
9357         Public tw As Tween.Twitter
9358         Public id As String
9359         Public user As TwitterDataModel.User
9360     End Class
9361
9362     Private Sub GetUserInfo_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
9363         Dim args As GetUserInfoArgs = DirectCast(e.Argument, GetUserInfoArgs)
9364         e.Result = args.tw.GetUserInfo(args.id, args.user)
9365     End Sub
9366
9367     Private Overloads Sub doShowUserStatus(ByVal id As String, ByVal ShowInputDialog As Boolean)
9368         Dim result As String = ""
9369         Dim user As TwitterDataModel.User = Nothing
9370         Dim args As New GetUserInfoArgs
9371         If ShowInputDialog Then
9372             Using inputName As New InputTabName()
9373                 inputName.FormTitle = "Show UserStatus"
9374                 inputName.FormDescription = My.Resources.FRMessage1
9375                 inputName.TabName = id
9376                 If inputName.ShowDialog() = Windows.Forms.DialogResult.OK AndAlso _
9377                    Not String.IsNullOrEmpty(inputName.TabName.Trim()) Then
9378                     id = inputName.TabName.Trim
9379                     args.tw = tw
9380                     args.id = id
9381                     args.user = user
9382                     Using _info As New FormInfo(Me, My.Resources.doShowUserStatusText1, _
9383                                                 AddressOf GetUserInfo_DoWork, _
9384                                                 Nothing, _
9385                                                 args)
9386                         _info.ShowDialog()
9387                         Dim ret As String = DirectCast(_info.Result, String)
9388                         If String.IsNullOrEmpty(ret) Then
9389                             doShowUserStatus(args.user)
9390                         Else
9391                             MessageBox.Show(ret)
9392                         End If
9393                     End Using
9394                 End If
9395             End Using
9396         Else
9397             args.tw = tw
9398             args.id = id
9399             args.user = user
9400             Using _info As New FormInfo(Me, My.Resources.doShowUserStatusText1, _
9401                                         AddressOf GetUserInfo_DoWork, _
9402                                         Nothing, _
9403                                         args)
9404                 _info.ShowDialog()
9405                 Dim ret As String = DirectCast(_info.Result, String)
9406                 If String.IsNullOrEmpty(ret) Then
9407                     doShowUserStatus(args.user)
9408                 Else
9409                     MessageBox.Show(ret)
9410                 End If
9411             End Using
9412         End If
9413     End Sub
9414
9415     Private Overloads Sub doShowUserStatus(ByVal user As TwitterDataModel.User)
9416         Using userinfo As New ShowUserInfo()
9417             userinfo.Owner = Me
9418             userinfo.User = user
9419             userinfo.ShowDialog(Me)
9420             Me.Activate()
9421         End Using
9422     End Sub
9423
9424     Private Overloads Sub ShowUserStatus(ByVal id As String, ByVal ShowInputDialog As Boolean)
9425         doShowUserStatus(id, ShowInputDialog)
9426     End Sub
9427
9428     Private Overloads Sub ShowUserStatus(ByVal id As String)
9429         doShowUserStatus(id, True)
9430     End Sub
9431
9432     Private Sub FollowToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FollowToolStripMenuItem.Click
9433         If NameLabel.Tag IsNot Nothing Then
9434             Dim id As String = DirectCast(NameLabel.Tag, String)
9435             If id <> tw.Username Then
9436                 FollowCommand(id)
9437             End If
9438         End If
9439     End Sub
9440
9441     Private Sub UnFollowToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UnFollowToolStripMenuItem.Click
9442         If NameLabel.Tag IsNot Nothing Then
9443             Dim id As String = DirectCast(NameLabel.Tag, String)
9444             If id <> tw.Username Then
9445                 RemoveCommand(id, False)
9446             End If
9447         End If
9448     End Sub
9449
9450     Private Sub ShowFriendShipToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ShowFriendShipToolStripMenuItem.Click
9451         If NameLabel.Tag IsNot Nothing Then
9452             Dim id As String = DirectCast(NameLabel.Tag, String)
9453             If id <> tw.Username Then
9454                 ShowFriendship(id)
9455             End If
9456         End If
9457     End Sub
9458
9459     Private Sub ShowUserStatusToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ShowUserStatusToolStripMenuItem.Click
9460         If NameLabel.Tag IsNot Nothing Then
9461             Dim id As String = DirectCast(NameLabel.Tag, String)
9462             ShowUserStatus(id, False)
9463         End If
9464     End Sub
9465
9466     Private Sub SearchPostsDetailNameToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchPostsDetailNameToolStripMenuItem.Click
9467         If NameLabel.Tag IsNot Nothing Then
9468             Dim id As String = DirectCast(NameLabel.Tag, String)
9469             AddNewTabForUserTimeline(id)
9470         End If
9471     End Sub
9472
9473     Private Sub SearchAtPostsDetailNameToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchAtPostsDetailNameToolStripMenuItem.Click
9474         If NameLabel.Tag IsNot Nothing Then
9475             Dim id As String = DirectCast(NameLabel.Tag, String)
9476             AddNewTabForSearch("@" + id)
9477         End If
9478     End Sub
9479
9480     Private Sub ShowProfileMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ShowProfileMenuItem.Click, ShowProfMenuItem.Click
9481         If _curPost IsNot Nothing Then
9482             ShowUserStatus(_curPost.ScreenName, False)
9483         End If
9484     End Sub
9485
9486     Private Sub GetRetweet_DoWork(ByVal sender As Object, ByVal e As ComponentModel.DoWorkEventArgs)
9487         Dim counter As Integer = 0
9488
9489         Dim statusid As Long
9490         If _curPost.RetweetedId > 0 Then
9491             statusid = _curPost.RetweetedId
9492         Else
9493             statusid = _curPost.StatusId
9494         End If
9495         tw.GetStatus_Retweeted_Count(statusid, counter)
9496
9497         e.Result = counter
9498     End Sub
9499
9500     Private Sub RtCountMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RtCountMenuItem.Click
9501         If Me.ExistCurrentPost Then
9502             Using _info As New FormInfo(Me, My.Resources.RtCountMenuItem_ClickText1, _
9503                             AddressOf GetRetweet_DoWork)
9504                 Dim retweet_count As Integer = 0
9505
9506                 ' ダイアログ表示
9507                 _info.ShowDialog()
9508                 retweet_count = CType(_info.Result, Integer)
9509                 If retweet_count < 0 Then
9510                     MessageBox.Show(My.Resources.RtCountText2)
9511                 Else
9512                     MessageBox.Show(retweet_count.ToString + My.Resources.RtCountText1)
9513                 End If
9514             End Using
9515         End If
9516     End Sub
9517
9518     Private WithEvents _hookGlobalHotkey As HookGlobalHotkey
9519     Public Sub New()
9520         _instance = Me
9521         _hookGlobalHotkey = New HookGlobalHotkey(Me)
9522         ' この呼び出しは、Windows フォーム デザイナで必要です。
9523         InitializeComponent()
9524
9525         ' InitializeComponent() 呼び出しの後で初期化を追加します。
9526
9527         Me._apiGauge.Control.Size = New Size(70, 22)
9528         Me._apiGauge.Control.Margin = New Padding(0, 3, 0, 2)
9529         Me._apiGauge.GaugeHeight = 8
9530         AddHandler Me._apiGauge.Control.DoubleClick, AddressOf Me.ApiInfoMenuItem_Click
9531         Me.StatusStrip1.Items.Insert(2, Me._apiGauge)
9532     End Sub
9533
9534     Private Sub _hookGlobalHotkey_HotkeyPressed(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles _hookGlobalHotkey.HotkeyPressed
9535         If (Me.WindowState = FormWindowState.Normal OrElse Me.WindowState = FormWindowState.Maximized) AndAlso Me.Visible AndAlso Form.ActiveForm Is Me Then
9536             'アイコン化
9537             Me.Visible = False
9538         ElseIf Form.ActiveForm Is Nothing Then
9539             Me.Visible = True
9540             If Me.WindowState = FormWindowState.Minimized Then Me.WindowState = FormWindowState.Normal
9541             Me.Activate()
9542             Me.StatusText.Focus()
9543         End If
9544     End Sub
9545
9546     Private Sub UserPicture_MouseEnter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UserPicture.MouseEnter
9547         Me.UserPicture.Cursor = Cursors.Hand
9548     End Sub
9549
9550     Private Sub UserPicture_MouseLeave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UserPicture.MouseLeave
9551         Me.UserPicture.Cursor = Cursors.Default
9552     End Sub
9553
9554     Private Sub UserPicture_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UserPicture.DoubleClick
9555         If NameLabel.Tag IsNot Nothing Then
9556             OpenUriAsync("http://twitter.com/" + NameLabel.Tag.ToString)
9557         End If
9558     End Sub
9559
9560     Private Sub SplitContainer2_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles SplitContainer2.MouseDoubleClick
9561         Me.MultiLineMenuItem.PerformClick()
9562     End Sub
9563
9564     Public ReadOnly Property CurPost As PostClass
9565         Get
9566             Return _curPost
9567         End Get
9568     End Property
9569
9570     Public ReadOnly Property IsPreviewEnable As Boolean
9571         Get
9572             Return SettingDialog.PreviewEnable
9573         End Get
9574     End Property
9575
9576 #Region "画像投稿"
9577     Private Sub ImageSelectMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ImageSelectMenuItem.Click
9578         If ImageSelectionPanel.Visible = True Then
9579             ImagefilePathText.CausesValidation = False
9580             TimelinePanel.Visible = True
9581             TimelinePanel.Enabled = True
9582             ImageSelectionPanel.Visible = False
9583             ImageSelectionPanel.Enabled = False
9584             DirectCast(ListTab.SelectedTab.Tag, DetailsListView).Focus()
9585             ImagefilePathText.CausesValidation = True
9586         Else
9587             ImageSelectionPanel.Visible = True
9588             ImageSelectionPanel.Enabled = True
9589             TimelinePanel.Visible = False
9590             TimelinePanel.Enabled = False
9591             ImagefilePathText.Focus()
9592         End If
9593     End Sub
9594
9595     Private Sub FilePickButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FilePickButton.Click
9596         If String.IsNullOrEmpty(Me.ImageService) Then Exit Sub
9597         OpenFileDialog1.Filter = Me.pictureService(Me.ImageService).GetFileOpenDialogFilter()
9598         OpenFileDialog1.Title = My.Resources.PickPictureDialog1
9599         OpenFileDialog1.FileName = ""
9600
9601         Try
9602             Me.AllowDrop = False
9603             If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub
9604         Finally
9605             Me.AllowDrop = True
9606         End Try
9607
9608         ImagefilePathText.Text = OpenFileDialog1.FileName
9609         ImageFromSelectedFile()
9610     End Sub
9611
9612     Private Sub ImagefilePathText_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ImagefilePathText.Validating
9613         If ImageCancelButton.Focused Then
9614             ImagefilePathText.CausesValidation = False
9615             Exit Sub
9616         End If
9617         ImagefilePathText.Text = Trim(ImagefilePathText.Text)
9618         If ImagefilePathText.Text = "" Then
9619             ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9620             ImageSelectedPicture.Tag = UploadFileType.Invalid
9621         Else
9622             ImageFromSelectedFile()
9623         End If
9624     End Sub
9625
9626     Private Sub ImageFromSelectedFile()
9627         Try
9628             If String.IsNullOrEmpty(Trim(ImagefilePathText.Text)) OrElse String.IsNullOrEmpty(Me.ImageService) Then
9629                 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9630                 ImageSelectedPicture.Tag = UploadFileType.Invalid
9631                 ImagefilePathText.Text = ""
9632                 Exit Sub
9633             End If
9634
9635             Dim fl As New FileInfo(Trim(ImagefilePathText.Text))
9636             If Not Me.pictureService(Me.ImageService).CheckValidExtension(fl.Extension) Then
9637                 '画像以外の形式
9638                 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9639                 ImageSelectedPicture.Tag = UploadFileType.Invalid
9640                 ImagefilePathText.Text = ""
9641                 Exit Sub
9642             End If
9643
9644             If Not Me.pictureService(Me.ImageService).CheckValidFilesize(fl.Extension, fl.Length) Then
9645                 ' ファイルサイズが大きすぎる
9646                 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9647                 ImageSelectedPicture.Tag = UploadFileType.Invalid
9648                 ImagefilePathText.Text = ""
9649                 MessageBox.Show("File is too large.")
9650                 Exit Sub
9651             End If
9652
9653             Select Case Me.pictureService(Me.ImageService).GetFileType(fl.Extension)
9654                 Case UploadFileType.Invalid
9655                     ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9656                     ImageSelectedPicture.Tag = UploadFileType.Invalid
9657                     ImagefilePathText.Text = ""
9658                 Case UploadFileType.Picture
9659                     Dim img As Image = Nothing
9660                     Using fs As New FileStream(ImagefilePathText.Text, FileMode.Open, FileAccess.Read)
9661                         img = Image.FromStream(fs)
9662                         fs.Close()
9663                     End Using
9664                     ImageSelectedPicture.Image = (New HttpVarious).CheckValidImage( _
9665                                 img, _
9666                                 img.Width, _
9667                                 img.Height)
9668                     ImageSelectedPicture.Tag = UploadFileType.Picture
9669                 Case UploadFileType.MultiMedia
9670                     ImageSelectedPicture.Image = My.Resources.MultiMediaImage
9671                     ImageSelectedPicture.Tag = UploadFileType.MultiMedia
9672                 Case Else
9673                     ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9674                     ImageSelectedPicture.Tag = UploadFileType.Invalid
9675                     ImagefilePathText.Text = ""
9676             End Select
9677
9678         Catch ex As FileNotFoundException
9679             ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9680             ImageSelectedPicture.Tag = UploadFileType.Invalid
9681             ImagefilePathText.Text = ""
9682             MessageBox.Show("File not found.")
9683         Catch ex As Exception
9684             ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9685             ImageSelectedPicture.Tag = UploadFileType.Invalid
9686             ImagefilePathText.Text = ""
9687             MessageBox.Show("The type of this file is not image.")
9688         End Try
9689     End Sub
9690
9691     Private Sub ImageSelection_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles _
9692         ImagefilePathText.KeyDown, _
9693         FilePickButton.KeyDown, _
9694         ImageServiceCombo.KeyDown
9695         If e.KeyCode = Keys.Escape Then
9696             ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9697             ImageSelectedPicture.Tag = UploadFileType.Invalid
9698             TimelinePanel.Visible = True
9699             TimelinePanel.Enabled = True
9700             ImageSelectionPanel.Visible = False
9701             ImageSelectionPanel.Enabled = False
9702             DirectCast(ListTab.SelectedTab.Tag, DetailsListView).Focus()
9703             ImagefilePathText.CausesValidation = True
9704         End If
9705     End Sub
9706
9707     Private Sub ImageSelection_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles _
9708     ImagefilePathText.KeyPress, _
9709     FilePickButton.KeyPress, _
9710     ImageServiceCombo.KeyPress
9711         If Convert.ToInt32(e.KeyChar) = &H1B Then
9712             ImagefilePathText.CausesValidation = False
9713             e.Handled = True
9714         End If
9715     End Sub
9716
9717     Private Sub ImageSelection_PreviewKeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles _
9718     ImagefilePathText.PreviewKeyDown, _
9719     FilePickButton.PreviewKeyDown, _
9720     ImageServiceCombo.PreviewKeyDown
9721         If e.KeyCode = Keys.Escape Then
9722             ImagefilePathText.CausesValidation = False
9723         End If
9724     End Sub
9725
9726     Private Sub SetImageServiceCombo()
9727         Dim svc As String = ""
9728         If ImageServiceCombo.SelectedIndex > -1 Then svc = ImageServiceCombo.SelectedItem.ToString
9729         ImageServiceCombo.Items.Clear()
9730         If SettingDialog.IsOAuth Then
9731             ImageServiceCombo.Items.Add("TwitPic")
9732             ImageServiceCombo.Items.Add("img.ly")
9733             ImageServiceCombo.Items.Add("yfrog")
9734             ImageServiceCombo.Items.Add("Plixi")
9735         Else
9736             ImageServiceCombo.Items.Add("")
9737             Exit Sub
9738         End If
9739         'ImageServiceCombo.Items.Add("TwitVideo")
9740         If svc = "" Then
9741             ImageServiceCombo.SelectedIndex = 0
9742         Else
9743             Dim idx As Integer = ImageServiceCombo.Items.IndexOf(svc)
9744             If idx = -1 Then
9745                 ImageServiceCombo.SelectedIndex = 0
9746             Else
9747                 ImageServiceCombo.SelectedIndex = idx
9748             End If
9749         End If
9750     End Sub
9751
9752     Private ReadOnly Property ImageService() As String
9753         Get
9754             Return CStr(ImageServiceCombo.SelectedItem)
9755         End Get
9756     End Property
9757
9758     Private Sub ImageCancelButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ImageCancelButton.Click
9759         ImagefilePathText.CausesValidation = False
9760         TimelinePanel.Visible = True
9761         TimelinePanel.Enabled = True
9762         ImageSelectionPanel.Visible = False
9763         ImageSelectionPanel.Enabled = False
9764         DirectCast(ListTab.SelectedTab.Tag, DetailsListView).Focus()
9765         ImagefilePathText.CausesValidation = True
9766     End Sub
9767
9768     Private Sub ImageServiceCombo_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ImageServiceCombo.SelectedIndexChanged
9769         If ImageSelectedPicture.Tag IsNot Nothing AndAlso Not String.IsNullOrEmpty(Me.ImageService) Then
9770             Try
9771                 Dim fi As New FileInfo(ImagefilePathText.Text.Trim)
9772                 If Not Me.pictureService(Me.ImageService).CheckValidFilesize(fi.Extension, fi.Length) Then
9773                     ImagefilePathText.Text = ""
9774                     ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9775                     ImageSelectedPicture.Tag = UploadFileType.Invalid
9776                 End If
9777             Catch ex As Exception
9778
9779             End Try
9780             _modifySettingCommon = True
9781             SaveConfigsAll(False)
9782         End If
9783     End Sub
9784 #End Region
9785
9786     Private Sub ListManageToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListManageToolStripMenuItem.Click
9787         Using form As New ListManage(tw)
9788             form.ShowDialog(Me)
9789         End Using
9790     End Sub
9791
9792     Public WriteOnly Property ModifySettingCommon() As Boolean
9793         Set(ByVal value As Boolean)
9794             _modifySettingCommon = value
9795         End Set
9796     End Property
9797
9798     Public WriteOnly Property ModifySettingLocal() As Boolean
9799         Set(ByVal value As Boolean)
9800             _modifySettingLocal = value
9801         End Set
9802     End Property
9803
9804     Public WriteOnly Property ModifySettingAtId() As Boolean
9805         Set(ByVal value As Boolean)
9806             _modifySettingAtId = value
9807         End Set
9808     End Property
9809
9810     Private Sub SourceLinkLabel_LinkClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles SourceLinkLabel.LinkClicked
9811         Dim link As String = CType(SourceLinkLabel.Tag, String)
9812         If Not String.IsNullOrEmpty(link) Then
9813             OpenUriAsync(link)
9814         End If
9815     End Sub
9816
9817     Private Sub SourceLinkLabel_MouseEnter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SourceLinkLabel.MouseEnter
9818         Dim link As String = CType(SourceLinkLabel.Tag, String)
9819         If Not String.IsNullOrEmpty(link) Then
9820             StatusLabelUrl.Text = link
9821         End If
9822     End Sub
9823
9824     Private Sub SourceLinkLabel_MouseLeave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SourceLinkLabel.MouseLeave
9825         SetStatusLabelUrl()
9826     End Sub
9827
9828     Private Sub MenuItemCommand_DropDownOpening(ByVal sender As Object, ByVal e As System.EventArgs) Handles MenuItemCommand.DropDownOpening
9829         If Me.ExistCurrentPost AndAlso Not _curPost.IsDm Then
9830             RtCountMenuItem.Enabled = True
9831         Else
9832             RtCountMenuItem.Enabled = False
9833         End If
9834     End Sub
9835
9836     Private Sub CopyUserIdStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CopyUserIdStripMenuItem.Click
9837         CopyUserId()
9838     End Sub
9839
9840     Private Sub CopyUserId()
9841         If _curPost Is Nothing Then Exit Sub
9842         Dim clstr As String = _curPost.ScreenName
9843         Try
9844             Clipboard.SetDataObject(clstr, False, 5, 100)
9845         Catch ex As Exception
9846             MessageBox.Show(ex.Message)
9847         End Try
9848     End Sub
9849
9850     Private Sub ShowRelatedStatusesMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ShowRelatedStatusesMenuItem.Click, ShowRelatedStatusesMenuItem2.Click
9851         Dim backToTab As TabClass = If(_curTab Is Nothing, _statuses.Tabs(ListTab.SelectedTab.Text), _statuses.Tabs(_curTab.Text))
9852         If Me.ExistCurrentPost AndAlso Not _curPost.IsDm Then
9853             'PublicSearchも除外した方がよい?
9854             If _statuses.GetTabByType(TabUsageType.Related) Is Nothing Then
9855                 Const TabName As String = "Related Tweets"
9856                 Dim tName As String = TabName
9857                 If Not Me.AddNewTab(tName, False, TabUsageType.Related) Then
9858                     For i As Integer = 2 To 100
9859                         tName = TabName + i.ToString()
9860                         If Me.AddNewTab(tName, False, TabUsageType.Related) Then
9861                             _statuses.AddTab(tName, TabUsageType.Related, Nothing)
9862                             Exit For
9863                         End If
9864                     Next
9865                 Else
9866                     _statuses.AddTab(tName, TabUsageType.Related, Nothing)
9867                 End If
9868                 _statuses.GetTabByName(tName).UnreadManage = False
9869                 _statuses.GetTabByName(tName).Notify = False
9870             End If
9871
9872             Dim tb As TabClass = _statuses.GetTabByType(TabUsageType.Related)
9873             tb.RelationTargetPost = _curPost
9874             Me.ClearTab(tb.TabName, False)
9875             For i As Integer = 0 To ListTab.TabPages.Count - 1
9876                 If tb.TabName = ListTab.TabPages(i).Text Then
9877                     ListTab.SelectedIndex = i
9878                     ListTabSelect(ListTab.TabPages(i))
9879                     Exit For
9880                 End If
9881             Next
9882
9883             GetTimeline(WORKERTYPE.Related, 1, 1, tb.TabName)
9884         End If
9885     End Sub
9886
9887     Private Sub CacheInfoMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CacheInfoMenuItem.Click
9888         Dim buf As New StringBuilder
9889         buf.AppendFormat("キャッシュメモリ容量         : {0}bytes({1}MB)" + vbCrLf, DirectCast(TIconDic, ImageDictionary).CacheMemoryLimit, DirectCast(TIconDic, ImageDictionary).CacheMemoryLimit / 1048576)
9890         buf.AppendFormat("物理メモリ使用割合           : {0}%" + vbCrLf, DirectCast(TIconDic, ImageDictionary).PhysicalMemoryLimit)
9891         buf.AppendFormat("キャッシュエントリ保持数     : {0}" + vbCrLf, DirectCast(TIconDic, ImageDictionary).CacheCount)
9892         buf.AppendFormat("キャッシュエントリ破棄数     : {0}" + vbCrLf, DirectCast(TIconDic, ImageDictionary).CacheRemoveCount)
9893         MessageBox.Show(buf.ToString, "アイコンキャッシュ使用状況")
9894     End Sub
9895
9896 #Region "Userstream"
9897     Private _isActiveUserstream As Boolean = False
9898
9899     Private Sub tw_PostDeleted(ByVal id As Long)
9900         Try
9901             If InvokeRequired AndAlso Not IsDisposed Then
9902                 Invoke(Sub()
9903                            _statuses.RemovePostReserve(id)
9904                            If _curTab IsNot Nothing AndAlso _statuses.Tabs(_curTab.Text).Contains(id) Then
9905                                _itemCache = Nothing
9906                                _itemCacheIndex = -1
9907                                _postCache = Nothing
9908                                DirectCast(_curTab.Tag, DetailsListView).Update()
9909                                If _curPost.StatusId = id Then DispSelectedPost(True)
9910                            End If
9911                        End Sub)
9912                 Exit Sub
9913             End If
9914         Catch ex As ObjectDisposedException
9915             Exit Sub
9916         End Try
9917     End Sub
9918
9919     Private Sub tw_NewPostFromStream()
9920         If SettingDialog.ReadOldPosts Then
9921             _statuses.SetRead() '新着時未読クリア
9922         End If
9923
9924         Dim rsltAddCount As Integer = _statuses.DistributePosts()
9925         SyncLock _syncObject
9926             Dim tm As Date = Now
9927             If _tlTimestamps.ContainsKey(tm) Then
9928                 _tlTimestamps(tm) += rsltAddCount
9929             Else
9930                 _tlTimestamps.Add(Now, rsltAddCount)
9931             End If
9932             Dim oneHour As Date = Now.Subtract(New TimeSpan(1, 0, 0))
9933             Dim keys As New List(Of Date)
9934             _tlCount = 0
9935             For Each key As Date In _tlTimestamps.Keys
9936                 If key.CompareTo(oneHour) < 0 Then
9937                     keys.Add(key)
9938                 Else
9939                     _tlCount += _tlTimestamps(key)
9940                 End If
9941             Next
9942             For Each key As Date In keys
9943                 _tlTimestamps.Remove(key)
9944             Next
9945             keys.Clear()
9946
9947             'Static before As DateTime = Now
9948             'If before.Subtract(Now).Seconds > -5 Then Exit Sub
9949             'before = Now
9950         End SyncLock
9951
9952         If SettingDialog.UserstreamPeriodInt > 0 Then Exit Sub
9953
9954         Try
9955             If InvokeRequired AndAlso Not IsDisposed Then
9956                 Invoke(New Action(Of Boolean)(AddressOf RefreshTimeline), True)
9957                 Exit Sub
9958             End If
9959         Catch ex As ObjectDisposedException
9960             Exit Sub
9961         End Try
9962     End Sub
9963
9964     Private Sub tw_UserStreamStarted()
9965         Me._isActiveUserstream = True
9966         If InvokeRequired AndAlso Not IsDisposed Then
9967             Invoke(New MethodInvoker(AddressOf tw_UserStreamStarted))
9968             Exit Sub
9969         End If
9970
9971         MenuItemUserStream.Text = "&UserStream ▶"
9972         MenuItemUserStream.Enabled = True
9973         StopToolStripMenuItem.Text = "&Stop"
9974         StopToolStripMenuItem.Enabled = True
9975
9976         StatusLabel.Text = "UserStream Started."
9977     End Sub
9978
9979     Private Sub tw_UserStreamStopped()
9980         Me._isActiveUserstream = False
9981         If InvokeRequired AndAlso Not IsDisposed Then
9982             Invoke(New MethodInvoker(AddressOf tw_UserStreamStopped))
9983             Exit Sub
9984         End If
9985
9986         MenuItemUserStream.Text = "&UserStream ■"
9987         MenuItemUserStream.Enabled = True
9988         StopToolStripMenuItem.Text = "&Start"
9989         StopToolStripMenuItem.Enabled = True
9990
9991         StatusLabel.Text = "UserStream Stopped."
9992     End Sub
9993
9994     Private Sub tw_UserStreamEventArrived(ByVal ev As Twitter.FormattedEvent)
9995         If InvokeRequired AndAlso Not IsDisposed Then
9996             Invoke(New Action(Of Twitter.FormattedEvent)(AddressOf tw_UserStreamEventArrived), ev)
9997             Exit Sub
9998         End If
9999         StatusLabel.Text = "Event: " + ev.Event
10000         'If ev.Event = "favorite" Then
10001         '    NotifyFavorite(ev)
10002         'End If
10003         NotifyEvent(ev)
10004         If ev.Event = "favorite" OrElse ev.Event = "unfavorite" Then
10005             If _curTab IsNot Nothing AndAlso _statuses.Tabs(_curTab.Text).Contains(ev.Id) Then
10006                 _itemCache = Nothing
10007                 _itemCacheIndex = -1
10008                 _postCache = Nothing
10009                 DirectCast(_curTab.Tag, DetailsListView).Update()
10010             End If
10011             If ev.Event = "unfavorite" AndAlso ev.Username.ToLower.Equals(tw.Username.ToLower) Then
10012                 RemovePostFromFavTab(New Int64() {ev.Id})
10013             End If
10014         End If
10015     End Sub
10016
10017     Private Sub NotifyEvent(ByVal ev As Twitter.FormattedEvent)
10018         '新着通知 
10019         If BalloonRequired(ev) Then
10020             NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning
10021             If SettingDialog.DispUsername Then NotifyIcon1.BalloonTipTitle = tw.Username + " - " Else NotifyIcon1.BalloonTipTitle = ""
10022             NotifyIcon1.BalloonTipTitle += "Tween [" + ev.Event.ToUpper() + "] by " + DirectCast(IIf(Not String.IsNullOrEmpty(ev.Username), ev.Username, ""), String)
10023             If Not String.IsNullOrEmpty(ev.Target) Then
10024                 NotifyIcon1.BalloonTipText = ev.Target
10025             Else
10026                 NotifyIcon1.BalloonTipText = " "
10027             End If
10028             NotifyIcon1.ShowBalloonTip(500)
10029         End If
10030
10031         'サウンド再生
10032         Dim snd As String = SettingDialog.EventSoundFile
10033         If Not _initial AndAlso SettingDialog.PlaySound AndAlso snd <> "" Then
10034             If CBool(ev.Eventtype And SettingDialog.EventNotifyFlag) AndAlso IsMyEventNotityAsEventType(ev) Then
10035                 Try
10036                     Dim dir As String = My.Application.Info.DirectoryPath
10037                     If Directory.Exists(Path.Combine(dir, "Sounds")) Then
10038                         dir = Path.Combine(dir, "Sounds")
10039                     End If
10040                     My.Computer.Audio.Play(Path.Combine(dir, snd), AudioPlayMode.Background)
10041                 Catch ex As Exception
10042
10043                 End Try
10044             End If
10045         End If
10046     End Sub
10047
10048     Private Sub StopToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StopToolStripMenuItem.Click
10049         MenuItemUserStream.Enabled = False
10050         If Me._isActiveUserstream Then
10051             tw.StopUserStream()
10052         Else
10053             tw.StartUserStream()
10054         End If
10055     End Sub
10056
10057     Private Sub TrackToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TrackToolStripMenuItem.Click
10058         Static inputTrack As String = ""
10059         If TrackToolStripMenuItem.Checked Then
10060             Using inputForm As New InputTabName
10061                 inputForm.TabName = inputTrack
10062                 inputForm.FormTitle = "Input track word"
10063                 inputForm.FormDescription = "Track word"
10064                 If inputForm.ShowDialog() <> Windows.Forms.DialogResult.OK Then
10065                     TrackToolStripMenuItem.Checked = False
10066                     Exit Sub
10067                 End If
10068                 inputTrack = inputForm.TabName.Trim()
10069             End Using
10070             If Not inputTrack.Equals(tw.TrackWord) Then
10071                 tw.TrackWord = inputTrack
10072                 Me._modifySettingCommon = True
10073                 TrackToolStripMenuItem.Checked = Not String.IsNullOrEmpty(inputTrack)
10074                 tw.ReconnectUserStream()
10075             End If
10076         Else
10077             tw.TrackWord = ""
10078             tw.ReconnectUserStream()
10079         End If
10080         Me._modifySettingCommon = True
10081     End Sub
10082
10083     Private Sub AllrepliesToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AllrepliesToolStripMenuItem.Click
10084         tw.AllAtReply = AllrepliesToolStripMenuItem.Checked
10085         Me._modifySettingCommon = True
10086         tw.ReconnectUserStream()
10087     End Sub
10088
10089     Private Sub EventViewerMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles EventViewerMenuItem.Click
10090         If evtDialog Is Nothing OrElse evtDialog.IsDisposed Then
10091             evtDialog = Nothing
10092             evtDialog = New EventViewerDialog
10093             evtDialog.Owner = Me
10094             '親の中央に表示
10095             Dim pos As Point = evtDialog.Location
10096             pos.X = Convert.ToInt32(Me.Location.X + Me.Size.Width / 2 - evtDialog.Size.Width / 2)
10097             pos.Y = Convert.ToInt32(Me.Location.Y + Me.Size.Height / 2 - evtDialog.Size.Height / 2)
10098             evtDialog.Location = pos
10099         End If
10100         evtDialog.EventSource = tw.StoredEvent
10101         If Not evtDialog.Visible Then
10102             evtDialog.Show(Me)
10103         Else
10104             evtDialog.Activate()
10105         End If
10106         Me.TopMost = Me.SettingDialog.AlwaysTop
10107     End Sub
10108 #End Region
10109
10110     Private Sub TweenRestartMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles TweenRestartMenuItem.Click
10111         _endingFlag = True
10112         Try
10113             Me.Close()
10114             Application.Restart()
10115         Catch ex As Exception
10116             MessageBox.Show("Failed to restart. Please run Tween manually.")
10117         End Try
10118     End Sub
10119
10120     Private Sub OpenOwnFavedMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles OpenOwnFavedMenuItem.Click
10121         If Not tw.Username = "" Then OpenUriAsync(My.Resources.FavstarUrl + "users/" + tw.Username + "/recent")
10122     End Sub
10123
10124     Private Sub OpenOwnHomeMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles OpenOwnHomeMenuItem.Click
10125         OpenUriAsync("http://twitter.com/" + tw.Username)
10126     End Sub
10127
10128     Private Sub doTranslation(ByVal str As String)
10129         Dim g As New Google
10130         Dim buf As String = ""
10131         If String.IsNullOrEmpty(str) Then Exit Sub
10132         Dim srclng As String = g.LanguageDetect(str)
10133         Dim dstlng As String = SettingDialog.TranslateLanguage
10134         Dim msg As String = ""
10135         If srclng <> dstlng AndAlso g.Translate(srclng, dstlng, str, buf, msg) Then
10136             PostBrowser.DocumentText = createDetailHtml(buf)
10137         Else
10138             If msg.StartsWith("Err:") Then
10139                 StatusLabel.Text = msg
10140             End If
10141         End If
10142     End Sub
10143
10144     Private Sub TranslationToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TranslationToolStripMenuItem.Click
10145         If Not Me.ExistCurrentPost Then Exit Sub
10146         doTranslation(_curPost.TextFromApi)
10147     End Sub
10148
10149     Private Sub SelectionTranslationToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectionTranslationToolStripMenuItem.Click
10150         doTranslation(WebBrowser_GetSelectionText(PostBrowser))
10151     End Sub
10152
10153     Private ReadOnly Property ExistCurrentPost As Boolean
10154         Get
10155             If _curPost Is Nothing Then Return False
10156             If _curPost.IsDeleted Then Return False
10157             Return True
10158         End Get
10159     End Property
10160
10161     Protected Overrides Sub Finalize()
10162         MyBase.Finalize()
10163     End Sub
10164
10165     Private Sub ShowUserTimelineToolStripMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ShowUserTimelineToolStripMenuItem.Click, ShowUserTimelineContextMenuItem.Click
10166         ShowUserTimeline()
10167     End Sub
10168
10169     Private Shared _instance As TweenMain
10170
10171     Public Shared Function GetInstance() As TweenMain
10172         Return _instance
10173     End Function
10174
10175     Public ReadOnly Property FavEventChangeUnread As Boolean
10176         Get
10177             Return SettingDialog.FavEventUnread
10178         End Get
10179     End Property
10180
10181     Private Function GetUserIdFromCurPostOrInput(ByVal caption As String) As String
10182         Dim id As String = ""
10183         If _curPost IsNot Nothing Then
10184             id = _curPost.ScreenName
10185         End If
10186         Using inputName As New InputTabName()
10187             inputName.FormTitle = caption
10188             inputName.FormDescription = My.Resources.FRMessage1
10189             inputName.TabName = id
10190             If inputName.ShowDialog() = Windows.Forms.DialogResult.OK AndAlso _
10191                Not String.IsNullOrEmpty(inputName.TabName.Trim()) Then
10192                 id = inputName.TabName.Trim
10193             Else
10194                 id = ""
10195             End If
10196         End Using
10197         Return id
10198     End Function
10199
10200     Private Sub UserTimelineToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UserTimelineToolStripMenuItem.Click
10201         Dim id As String = GetUserIdFromCurPostOrInput("Show UserTimeline")
10202         If Not String.IsNullOrEmpty(id) Then
10203             AddNewTabForUserTimeline(id)
10204         End If
10205     End Sub
10206
10207     Private Sub UserFavorareToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UserFavorareToolStripMenuItem.Click
10208         Dim id As String = GetUserIdFromCurPostOrInput("Show Favstar")
10209         If Not String.IsNullOrEmpty(id) Then
10210             OpenUriAsync(My.Resources.FavstarUrl + "users/" + id + "/recent")
10211         End If
10212     End Sub
10213
10214     Private Sub SystemEvents_PowerModeChanged(ByVal sender As Object, ByVal e As Microsoft.Win32.PowerModeChangedEventArgs)
10215         If e.Mode = Microsoft.Win32.PowerModes.Resume Then osResumed = True
10216     End Sub
10217
10218 End Class