OSDN Git Service

Ctrl-j/kが効かなかったので修正
[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 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)
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         If displayItem IsNot Nothing Then
4729             RemoveHandler displayItem.ImageDownloaded, AddressOf Me.DisplayItemImage_Downloaded
4730             displayItem = Nothing
4731         End If
4732         displayItem = DirectCast(_curList.Items(_curList.SelectedIndices(0)), ImageListViewItem)
4733         AddHandler displayItem.ImageDownloaded, AddressOf Me.DisplayItemImage_Downloaded
4734
4735         Dim dTxt As String = createDetailHtml(If(_curPost.IsDeleted, "(DELETED)", _curPost.Text))
4736         If _curPost.IsDm Then
4737             SourceLinkLabel.Tag = Nothing
4738             SourceLinkLabel.Text = ""
4739         Else
4740             Dim mc As Match = Regex.Match(_curPost.SourceHtml, "<a href=""(?<sourceurl>.+?)""")
4741             If mc.Success Then
4742                 Dim src As String = mc.Groups("sourceurl").Value
4743                 SourceLinkLabel.Tag = mc.Groups("sourceurl").Value
4744                 mc = Regex.Match(src, "^https?://")
4745                 If Not mc.Success Then
4746                     src = src.Insert(0, "http://twitter.com")
4747                 End If
4748                 SourceLinkLabel.Tag = src
4749             Else
4750                 SourceLinkLabel.Tag = Nothing
4751             End If
4752             If String.IsNullOrEmpty(_curPost.Source) Then
4753                 SourceLinkLabel.Text = ""
4754                 'SourceLinkLabel.Visible = False
4755             Else
4756                 SourceLinkLabel.Text = _curPost.Source
4757                 'SourceLinkLabel.Visible = True
4758             End If
4759         End If
4760         SourceLinkLabel.TabStop = False
4761
4762         If _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage AndAlso Not _curPost.IsOwl Then
4763             NameLabel.Text = "DM TO -> "
4764         ElseIf _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage Then
4765             NameLabel.Text = "DM FROM <- "
4766         Else
4767             NameLabel.Text = ""
4768         End If
4769         NameLabel.Text += _curPost.ScreenName + "/" + _curPost.Nickname
4770         NameLabel.Tag = _curPost.ScreenName
4771         If Not String.IsNullOrEmpty(_curPost.RetweetedBy) Then
4772             NameLabel.Text += " (RT:" + _curPost.RetweetedBy + ")"
4773         End If
4774         If UserPicture.Image IsNot Nothing Then UserPicture.Image.Dispose()
4775         If Not String.IsNullOrEmpty(_curPost.ImageUrl) AndAlso TIconDic(_curPost.ImageUrl) IsNot Nothing Then
4776             Try
4777                 UserPicture.Image = New Bitmap(TIconDic(_curPost.ImageUrl))
4778             Catch ex As Exception
4779                 UserPicture.Image = Nothing
4780             End Try
4781         Else
4782             UserPicture.Image = Nothing
4783         End If
4784
4785         NameLabel.ForeColor = System.Drawing.SystemColors.ControlText
4786         DateTimeLabel.Text = _curPost.CreatedAt.ToString()
4787         If _curPost.IsOwl AndAlso (SettingDialog.OneWayLove OrElse _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage) Then NameLabel.ForeColor = _clOWL
4788         If _curPost.RetweetedId > 0 Then NameLabel.ForeColor = _clRetweet
4789         If _curPost.IsFav Then NameLabel.ForeColor = _clFav
4790
4791         If DumpPostClassToolStripMenuItem.Checked Then
4792             Dim sb As New StringBuilder(512)
4793
4794             sb.Append("-----Start PostClass Dump<br>")
4795             sb.AppendFormat("TextFromApi           : {0}<br>", _curPost.TextFromApi)
4796             sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.TextFromApi)
4797             sb.AppendFormat("StatusId             : {0}<br>", _curPost.StatusId.ToString)
4798             'sb.AppendFormat("ImageIndex     : {0}<br>", _curPost.ImageIndex.ToString)
4799             sb.AppendFormat("ImageUrl       : {0}<br>", _curPost.ImageUrl)
4800             sb.AppendFormat("InReplyToStatusId    : {0}<br>", _curPost.InReplyToStatusId.ToString)
4801             sb.AppendFormat("InReplyToUser  : {0}<br>", _curPost.InReplyToUser)
4802             sb.AppendFormat("IsDM           : {0}<br>", _curPost.IsDm.ToString)
4803             sb.AppendFormat("IsFav          : {0}<br>", _curPost.IsFav.ToString)
4804             sb.AppendFormat("IsMark         : {0}<br>", _curPost.IsMark.ToString)
4805             sb.AppendFormat("IsMe           : {0}<br>", _curPost.IsMe.ToString)
4806             sb.AppendFormat("IsOwl          : {0}<br>", _curPost.IsOwl.ToString)
4807             sb.AppendFormat("IsProtect      : {0}<br>", _curPost.IsProtect.ToString)
4808             sb.AppendFormat("IsRead         : {0}<br>", _curPost.IsRead.ToString)
4809             sb.AppendFormat("IsReply        : {0}<br>", _curPost.IsReply.ToString)
4810
4811             For Each nm As String In _curPost.ReplyToList
4812                 sb.AppendFormat("ReplyToList    : {0}<br>", nm)
4813             Next
4814
4815             sb.AppendFormat("ScreenName           : {0}<br>", _curPost.ScreenName)
4816             sb.AppendFormat("NickName       : {0}<br>", _curPost.Nickname)
4817             sb.AppendFormat("Text   : {0}<br>", _curPost.Text)
4818             sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.Text)
4819             sb.AppendFormat("CreatedAt          : {0}<br>", _curPost.CreatedAt.ToString)
4820             sb.AppendFormat("Source         : {0}<br>", _curPost.Source)
4821             sb.AppendFormat("UserId            : {0}<br>", _curPost.UserId)
4822             sb.AppendFormat("FilterHit      : {0}<br>", _curPost.FilterHit)
4823             sb.AppendFormat("RetweetedBy    : {0}<br>", _curPost.RetweetedBy)
4824             sb.AppendFormat("RetweetedId    : {0}<br>", _curPost.RetweetedId)
4825             sb.AppendFormat("SearchTabName  : {0}<br>", _curPost.RelTabName)
4826             sb.Append("-----End PostClass Dump<br>")
4827
4828             PostBrowser.Visible = False
4829             PostBrowser.DocumentText = detailHtmlFormatHeader + sb.ToString + detailHtmlFormatFooter
4830             PostBrowser.Visible = True
4831         Else
4832             Try
4833                 If PostBrowser.DocumentText <> dTxt Then
4834                     PostBrowser.Visible = False
4835                     PostBrowser.DocumentText = dTxt
4836                     Dim lnks As New List(Of String)
4837                     For Each lnk As Match In Regex.Matches(dTxt, "<a target=""_self"" href=""(?<url>http[^""]+)""", RegexOptions.IgnoreCase)
4838                         lnks.Add(lnk.Result("${url}"))
4839                     Next
4840                     Thumbnail.thumbnail(_curPost.StatusId, lnks)
4841                 End If
4842             Catch ex As System.Runtime.InteropServices.COMException
4843                 '原因不明
4844             Finally
4845                 PostBrowser.Visible = True
4846             End Try
4847         End If
4848     End Sub
4849
4850     Private Sub MatomeMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MatomeMenuItem.Click
4851         OpenUriAsync("http://sourceforge.jp/projects/tween/wiki/FrontPage")
4852     End Sub
4853
4854     Private Sub ShortcutKeyListMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ShortcutKeyListMenuItem.Click
4855         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")
4856     End Sub
4857
4858     Private Sub ListTab_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles ListTab.KeyDown
4859         If ListTab.SelectedTab IsNot Nothing Then
4860             If _statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.PublicSearch Then
4861                 Dim pnl As Control = ListTab.SelectedTab.Controls("panelSearch")
4862                 If pnl.Controls("comboSearch").Focused OrElse _
4863                    pnl.Controls("comboLang").Focused OrElse _
4864                    pnl.Controls("buttonSearch").Focused Then Exit Sub
4865             End If
4866             Dim State As ModifierState = GetModifierState(e.Control, e.Shift, e.Alt)
4867             If State = ModifierState.NotFlags Then Exit Sub
4868             If State <> ModifierState.None Then _anchorFlag = False
4869             If CommonKeyDown(e.KeyCode, FocusedControl.ListTab, State) Then
4870                 e.Handled = True
4871                 e.SuppressKeyPress = True
4872             End If
4873         End If
4874
4875     End Sub
4876
4877     Private Function GetModifierState(ByVal sControl As Boolean, ByVal sShift As Boolean, ByVal sAlt As Boolean) As ModifierState
4878         Dim state As ModifierState = ModifierState.None
4879         If sControl Then state = state Or ModifierState.Ctrl
4880         If sShift Then state = state Or ModifierState.Shift
4881         If sAlt Then state = state Or ModifierState.Alt
4882         Return state
4883     End Function
4884
4885     <FlagsAttribute()> _
4886     Private Enum ModifierState As Integer
4887         None = 0
4888         Alt = 1
4889         Shift = 2
4890         Ctrl = 4
4891         'CShift = 11
4892         'CAlt = 12
4893         'AShift = 13
4894         NotFlags = 8
4895
4896         'ListTab = 101
4897         'PostBrowser = 102
4898         'StatusText = 103
4899     End Enum
4900
4901     Private Enum FocusedControl As Integer
4902         None
4903         ListTab
4904         StatusText
4905         PostBrowser
4906     End Enum
4907
4908     Private Function CommonKeyDown(ByVal KeyCode As System.Windows.Forms.Keys, ByVal Focused As FocusedControl, ByVal Modifier As ModifierState) As Boolean
4909         'リストのカーソル移動関係(上下キー、PageUp/Downに該当)
4910         If Focused = FocusedControl.ListTab Then
4911             If Modifier = (ModifierState.Ctrl Or ModifierState.Shift) OrElse
4912                 Modifier = ModifierState.Ctrl OrElse
4913                 Modifier = ModifierState.None OrElse
4914                 Modifier = ModifierState.Shift Then
4915                 If KeyCode = Keys.J Then
4916                     SendKeys.Send("{DOWN}")
4917                     Return True
4918                 ElseIf KeyCode = Keys.K Then
4919                     SendKeys.Send("{UP}")
4920                     Return True
4921                 End If
4922             End If
4923             If Modifier = ModifierState.Shift OrElse
4924                 Modifier = ModifierState.None Then
4925                 If KeyCode = Keys.F Then
4926                     SendKeys.Send("{PGDN}")
4927                     Return True
4928                 ElseIf KeyCode = Keys.B Then
4929                     SendKeys.Send("{PGUP}")
4930                     Return True
4931                 End If
4932             End If
4933         End If
4934
4935         '修飾キーなし
4936         Select Case Modifier
4937             Case ModifierState.None
4938                 'フォーカス関係なし
4939                 Select Case KeyCode
4940                     Case Keys.F1
4941                         OpenUriAsync("http://sourceforge.jp/projects/tween/wiki/FrontPage")
4942                         Return True
4943                     Case Keys.F3
4944                         MenuItemSearchNext_Click(Nothing, Nothing)
4945                         Return True
4946                     Case Keys.F5
4947                         DoRefresh()
4948                         Return True
4949                     Case Keys.F6
4950                         GetTimeline(WORKERTYPE.Reply, 1, 0, "")
4951                         Return True
4952                     Case Keys.F7
4953                         GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0, "")
4954                         Return True
4955                 End Select
4956                 If Focused <> FocusedControl.StatusText Then
4957                     'フォーカスStatusText以外
4958                     Select Case KeyCode
4959                         Case Keys.Space, Keys.ProcessKey
4960                             If Focused = FocusedControl.ListTab Then _anchorFlag = False
4961                             JumpUnreadMenuItem_Click(Nothing, Nothing)
4962                             Return True
4963                         Case Keys.G
4964                             If Focused = FocusedControl.ListTab Then _anchorFlag = False
4965                             ShowRelatedStatusesMenuItem_Click(Nothing, Nothing)
4966                             Return True
4967                     End Select
4968                 End If
4969                 If Focused = FocusedControl.ListTab Then
4970                     'フォーカスList
4971                     Select Case KeyCode
4972                         Case Keys.N, Keys.Right
4973                             GoRelPost(True)
4974                             Return True
4975                         Case Keys.P, Keys.Left
4976                             GoRelPost(False)
4977                             Return True
4978                         Case Keys.OemPeriod
4979                             GoAnchor()
4980                             Return True
4981                         Case Keys.I
4982                             If Me.StatusText.Enabled Then Me.StatusText.Focus()
4983                             Return True
4984                         Case Keys.Enter, Keys.Return
4985                             MakeReplyOrDirectStatus()
4986                             Return True
4987                         Case Keys.R
4988                             DoRefresh()
4989                             Return True
4990                     End Select
4991                     '以下、アンカー初期化
4992                     _anchorFlag = False
4993                     Select Case KeyCode
4994                         Case Keys.L
4995                             GoPost(True)
4996                             Return True
4997                         Case Keys.H
4998                             GoPost(False)
4999                             Return True
5000                         Case Keys.Z, Keys.Oemcomma
5001                             MoveTop()
5002                             Return True
5003                         Case Keys.S
5004                             GoNextTab(True)
5005                             Return True
5006                         Case Keys.A
5007                             GoNextTab(False)
5008                             Return True
5009                         Case Keys.Oem4
5010                             ' ] in_reply_to参照元へ戻る
5011                             GoInReplyToPostTree()
5012                             Return True
5013                         Case Keys.Oem6
5014                             ' [ in_reply_toへジャンプ
5015                             GoBackInReplyToPostTree()
5016                             Return True
5017                         Case Keys.Escape
5018                             If ListTab.SelectedTab IsNot Nothing Then
5019                                 Dim tabtype As TabUsageType = _statuses.Tabs(ListTab.SelectedTab.Text).TabType
5020                                 If tabtype = TabUsageType.Related OrElse tabtype = TabUsageType.UserTimeline Then
5021                                     Dim relTp As TabPage = ListTab.SelectedTab
5022                                     RemoveSpecifiedTab(relTp.Text, False)
5023                                     SaveConfigsTabs()
5024                                     Return True
5025                                 End If
5026                             End If
5027                     End Select
5028                 End If
5029             Case ModifierState.Ctrl
5030                 'フォーカス関係なし
5031                 Select Case KeyCode
5032                     Case Keys.R
5033                         MakeReplyOrDirectStatus(False, True)
5034                         Return True
5035                     Case Keys.D
5036                         doStatusDelete()
5037                         Return True
5038                     Case Keys.M
5039                         MakeReplyOrDirectStatus(False, False)
5040                         Return True
5041                     Case Keys.S
5042                         FavoriteChange(True)
5043                         Return True
5044                     Case Keys.I
5045                         doRepliedStatusOpen()
5046                         Return True
5047                     Case Keys.Q
5048                         doQuote()
5049                         Return True
5050                     Case Keys.B
5051                         ReadedStripMenuItem_Click(Nothing, Nothing)
5052                         Return True
5053                     Case Keys.T
5054                         HashManageMenuItem_Click(Nothing, Nothing)
5055                         Return True
5056                     Case Keys.L
5057                         UrlConvertAutoToolStripMenuItem_Click(Nothing, Nothing)
5058                         Return True
5059                     Case Keys.Y
5060                         If Not Focused = FocusedControl.PostBrowser Then
5061                             MultiLineMenuItem_Click(Nothing, Nothing)
5062                             Return True
5063                         End If
5064                     Case Keys.F
5065                         MenuItemSubSearch_Click(Nothing, Nothing)
5066                         Return True
5067                     Case Keys.U
5068                         ShowUserTimeline()
5069                         Return True
5070                     Case Keys.H
5071                         ' Webページを開く動作
5072                         If _curList.SelectedIndices.Count > 0 Then
5073                             OpenUriAsync("http://twitter.com/" + GetCurTabPost(_curList.SelectedIndices(0)).ScreenName)
5074                         ElseIf _curList.SelectedIndices.Count = 0 Then
5075                             OpenUriAsync("http://twitter.com/")
5076                         End If
5077                         Return True
5078                     Case Keys.G
5079                         ' Webページを開く動作
5080                         If _curList.SelectedIndices.Count > 0 Then
5081                             OpenUriAsync("http://twitter.com/" + GetCurTabPost(_curList.SelectedIndices(0)).ScreenName + "/favorites")
5082                         End If
5083                         Return True
5084                     Case Keys.O
5085                         ' Webページを開く動作
5086                         StatusOpenMenuItem_Click(Nothing, Nothing)
5087                         Return True
5088                     Case Keys.E
5089                         ' Webページを開く動作
5090                         OpenURLMenuItem_Click(Nothing, Nothing)
5091                         Return True
5092                 End Select
5093                 'フォーカスList
5094                 If Focused = FocusedControl.ListTab Then
5095                     Select Case KeyCode
5096                         Case Keys.Home, Keys.End
5097                             _colorize = True
5098                             Return False            'スルーする
5099                         Case Keys.N
5100                             GoNextTab(True)
5101                             Return True
5102                         Case Keys.P
5103                             GoNextTab(False)
5104                             Return True
5105                         Case Keys.C
5106                             CopyStot()
5107                             Return True
5108                         Case Keys.D1, Keys.D2, Keys.D3, Keys.D4, Keys.D5, Keys.D6, Keys.D7, Keys.D8
5109                             ' タブダイレクト選択(Ctrl+1~8,Ctrl+9)
5110                             Dim tabNo As Integer = KeyCode - Keys.D1
5111                             If ListTab.TabPages.Count < tabNo Then
5112                                 Exit Function
5113                             End If
5114                             ListTab.SelectedIndex = tabNo
5115                             ListTabSelect(ListTab.TabPages(tabNo))
5116                             Return True
5117                         Case Keys.D9
5118                             ListTab.SelectedIndex = ListTab.TabPages.Count - 1
5119                             ListTabSelect(ListTab.TabPages(ListTab.TabPages.Count - 1))
5120                             Return True
5121                     End Select
5122                 ElseIf Focused = FocusedControl.StatusText Then
5123                     'フォーカスStatusText
5124                     Select Case KeyCode
5125                         Case Keys.A
5126                             StatusText.SelectAll()
5127                             Return True
5128                         Case Keys.Up, Keys.Down
5129                             If StatusText.Text.Trim() <> "" Then
5130                                 _history(_hisIdx) = New PostingStatus(StatusText.Text, _reply_to_id, _reply_to_name)
5131                             End If
5132                             If KeyCode = Keys.Up Then
5133                                 _hisIdx -= 1
5134                                 If _hisIdx < 0 Then _hisIdx = 0
5135                             Else
5136                                 _hisIdx += 1
5137                                 If _hisIdx > _history.Count - 1 Then _hisIdx = _history.Count - 1
5138                             End If
5139                             StatusText.Text = _history(_hisIdx).status
5140                             _reply_to_id = _history(_hisIdx).inReplyToId
5141                             _reply_to_name = _history(_hisIdx).inReplyToName
5142                             StatusText.SelectionStart = StatusText.Text.Length
5143                             Return True
5144                         Case Keys.PageUp, Keys.P
5145                             If ListTab.SelectedIndex = 0 Then
5146                                 ListTab.SelectedIndex = ListTab.TabCount - 1
5147                             Else
5148                                 ListTab.SelectedIndex -= 1
5149                             End If
5150                             StatusText.Focus()
5151                             Return True
5152                         Case Keys.PageDown, Keys.N
5153                             If ListTab.SelectedIndex = ListTab.TabCount - 1 Then
5154                                 ListTab.SelectedIndex = 0
5155                             Else
5156                                 ListTab.SelectedIndex += 1
5157                             End If
5158                             StatusText.Focus()
5159                             Return True
5160                     End Select
5161                 Else
5162                     'フォーカスPostBrowserもしくは関係なし
5163                     Select Case KeyCode
5164                         Case Keys.A
5165                             PostBrowser.Document.ExecCommand("SelectAll", False, Nothing)
5166                             Return True
5167                         Case Keys.C, Keys.Insert
5168                             Dim _selText As String = WebBrowser_GetSelectionText(PostBrowser)
5169                             If Not String.IsNullOrEmpty(_selText) Then
5170                                 Try
5171                                     Clipboard.SetDataObject(_selText, False, 5, 100)
5172                                 Catch ex As Exception
5173                                     MessageBox.Show(ex.Message)
5174                                 End Try
5175                             End If
5176                             Return True
5177                         Case Keys.Y
5178                             MultiLineMenuItem.Checked = Not MultiLineMenuItem.Checked
5179                             MultiLineMenuItem_Click(Nothing, Nothing)
5180                             Return True
5181                     End Select
5182                 End If
5183             Case ModifierState.Shift
5184                 'フォーカス関係なし
5185                 Select Case KeyCode
5186                     Case Keys.F3
5187                         MenuItemSearchPrev_Click(Nothing, Nothing)
5188                         Return True
5189                     Case Keys.F5
5190                         DoRefreshMore()
5191                         Return True
5192                     Case Keys.F6
5193                         GetTimeline(WORKERTYPE.Reply, -1, 0, "")
5194                         Return True
5195                     Case Keys.F7
5196                         GetTimeline(WORKERTYPE.DirectMessegeRcv, -1, 0, "")
5197                         Return True
5198                 End Select
5199                 'フォーカスStatusText以外
5200                 If Focused <> FocusedControl.StatusText Then
5201                     If KeyCode = Keys.R Then
5202                         DoRefreshMore()
5203                         Return True
5204                     End If
5205                 End If
5206                 'フォーカスリスト
5207                 If Focused = FocusedControl.ListTab Then
5208                     Select Case KeyCode
5209                         Case Keys.H
5210                             GoTopEnd(True)
5211                             Return True
5212                         Case Keys.L
5213                             GoTopEnd(False)
5214                             Return True
5215                         Case Keys.M
5216                             GoMiddle()
5217                             Return True
5218                         Case Keys.G
5219                             GoLast()
5220                             Return True
5221                         Case Keys.Z
5222                             MoveMiddle()
5223                             Return True
5224                         Case Keys.Oem4
5225                             GoBackInReplyToPostTree(True, False)
5226                             Return True
5227                         Case Keys.Oem6
5228                             GoBackInReplyToPostTree(True, True)
5229                             Return True
5230                         Case Keys.N, Keys.Right
5231                             ' お気に入り前後ジャンプ(SHIFT+N←/P→)
5232                             GoFav(True)
5233                             Return True
5234                         Case Keys.P, Keys.Left
5235                             ' お気に入り前後ジャンプ(SHIFT+N←/P→)
5236                             GoFav(False)
5237                             Return True
5238                     End Select
5239                 End If
5240             Case ModifierState.Alt
5241                 Select Case KeyCode
5242                     Case Keys.R
5243                         doReTweetOfficial(True)
5244                         Return True
5245                     Case Keys.P
5246                         If _curPost IsNot Nothing Then
5247                             doShowUserStatus(_curPost.ScreenName, False)
5248                             Return True
5249                         End If
5250                     Case Keys.Up
5251                         ScrollDownPostBrowser(False)
5252                         Return True
5253                     Case Keys.Down
5254                         ScrollDownPostBrowser(True)
5255                         Return True
5256                     Case Keys.PageUp
5257                         PageDownPostBrowser(False)
5258                         Return True
5259                     Case Keys.PageDown
5260                         PageDownPostBrowser(True)
5261                         Return True
5262                 End Select
5263                 If Focused = FocusedControl.ListTab Then
5264                     ' 別タブの同じ書き込みへ(ALT+←/→)
5265                     If KeyCode = Keys.Right Then
5266                         GoSamePostToAnotherTab(False)
5267                         Return True
5268                     ElseIf KeyCode = Keys.Left Then
5269                         GoSamePostToAnotherTab(True)
5270                         Return True
5271                     End If
5272                 End If
5273             Case ModifierState.Ctrl Or ModifierState.Shift
5274                 Select Case KeyCode
5275                     Case Keys.R
5276                         MakeReplyOrDirectStatus(False, True, True)
5277                         Return True
5278                     Case Keys.C
5279                         CopyIdUri()
5280                         Return True
5281                     Case Keys.F
5282                         If ListTab.SelectedTab IsNot Nothing Then
5283                             If _statuses.Tabs(ListTab.SelectedTab.Text).TabType <> TabUsageType.PublicSearch Then
5284                                 ListTab.SelectedTab.Controls("panelSearch").Controls("comboSearch").Focus()
5285                                 Return True
5286                             End If
5287                         End If
5288                     Case Keys.S
5289                         FavoriteChange(False)
5290                         Return True
5291                     Case Keys.B
5292                         UnreadStripMenuItem_Click(Nothing, Nothing)
5293                         Return True
5294                     Case Keys.T
5295                         HashToggleMenuItem_Click(Nothing, Nothing)
5296                         Return True
5297                     Case Keys.P
5298                         ImageSelectMenuItem_Click(Nothing, Nothing)
5299                         Return True
5300                     Case Keys.H
5301                         doMoveToRTHome()
5302                         Return True
5303                     Case Keys.O
5304                         FavorareMenuItem_Click(Nothing, Nothing)
5305                         Return True
5306                 End Select
5307                 If Focused = FocusedControl.StatusText Then
5308                     Select Case KeyCode
5309                         Case Keys.Up
5310                             Dim idx As Integer = 0
5311                             If _curList IsNot Nothing AndAlso _curList.Items.Count <> 0 AndAlso _
5312                                         _curList.SelectedIndices.Count > 0 AndAlso _curList.SelectedIndices(0) > 0 Then
5313                                 idx = _curList.SelectedIndices(0) - 1
5314                                 SelectListItem(_curList, idx)
5315                                 _curList.EnsureVisible(idx)
5316                                 Return True
5317                             End If
5318                         Case Keys.Down
5319                             Dim idx As Integer = 0
5320                             If _curList IsNot Nothing AndAlso _curList.Items.Count <> 0 AndAlso _curList.SelectedIndices.Count > 0 _
5321                                         AndAlso _curList.SelectedIndices(0) < _curList.Items.Count - 1 Then
5322                                 idx = _curList.SelectedIndices(0) + 1
5323                                 SelectListItem(_curList, idx)
5324                                 _curList.EnsureVisible(idx)
5325                                 Return True
5326                             End If
5327                         Case Keys.Space
5328                             If StatusText.SelectionStart > 0 Then
5329                                 Dim endidx As Integer = StatusText.SelectionStart - 1
5330                                 Dim startstr As String = ""
5331                                 Dim pressed As Boolean = False
5332                                 For i As Integer = StatusText.SelectionStart - 1 To 0 Step -1
5333                                     Dim c As Char = StatusText.Text.Chars(i)
5334                                     If Char.IsLetterOrDigit(c) OrElse c = "_" Then
5335                                         Continue For
5336                                     End If
5337                                     If c = "@" Then
5338                                         pressed = True
5339                                         startstr = StatusText.Text.Substring(i + 1, endidx - i)
5340                                         ShowSuplDialog(StatusText, AtIdSupl, startstr.Length + 1, startstr)
5341                                     ElseIf c = "#" Then
5342                                         pressed = True
5343                                         startstr = StatusText.Text.Substring(i + 1, endidx - i)
5344                                         ShowSuplDialog(StatusText, HashSupl, startstr.Length + 1, startstr)
5345                                     Else
5346                                         Exit For
5347                                     End If
5348                                 Next
5349                                 Return pressed
5350                             End If
5351                     End Select
5352                 End If
5353             Case ModifierState.Ctrl Or ModifierState.Alt
5354                 If KeyCode = Keys.S Then
5355                     FavoritesRetweetOriginal()
5356                     Return True
5357                 ElseIf KeyCode = Keys.R Then
5358                     FavoritesRetweetUnofficial()
5359                     Return True
5360                 End If
5361             Case ModifierState.Alt Or ModifierState.Shift
5362                 If Focused = FocusedControl.PostBrowser Then
5363                     If KeyCode = Keys.R Then
5364                         doReTweetUnofficial()
5365                     ElseIf KeyCode = Keys.C Then
5366                         CopyUserId()
5367                     End If
5368                     Return True
5369                 End If
5370                 Select Case KeyCode
5371                     Case Keys.R
5372                         doReTweetUnofficial()
5373                         Return True
5374                     Case Keys.C
5375                         CopyUserId()
5376                         Return True
5377                     Case Keys.Up
5378                         Thumbnail.ScrollThumbnail(False)
5379                         Return True
5380                     Case Keys.Down
5381                         Thumbnail.ScrollThumbnail(True)
5382                         Return True
5383                 End Select
5384                 If Focused = FocusedControl.ListTab AndAlso KeyCode = Keys.Enter Then
5385                     If Not Me.SplitContainer3.Panel2Collapsed Then
5386                         Thumbnail.OpenPicture()
5387                     End If
5388                     Return True
5389                 End If
5390         End Select
5391     End Function
5392
5393     Private Sub ScrollDownPostBrowser(ByVal forward As Boolean)
5394         Dim doc As HtmlDocument = PostBrowser.Document
5395         If doc Is Nothing Then Exit Sub
5396         If doc.Body Is Nothing Then Exit Sub
5397
5398         If forward Then
5399             doc.Body.ScrollTop += SettingDialog.FontDetail.Height
5400         Else
5401             doc.Body.ScrollTop -= SettingDialog.FontDetail.Height
5402         End If
5403     End Sub
5404
5405     Private Sub PageDownPostBrowser(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 += PostBrowser.ClientRectangle.Height - SettingDialog.FontDetail.Height
5412         Else
5413             doc.Body.ScrollTop -= PostBrowser.ClientRectangle.Height - SettingDialog.FontDetail.Height
5414         End If
5415     End Sub
5416
5417     Private Sub GoNextTab(ByVal forward As Boolean)
5418         Dim idx As Integer = ListTab.SelectedIndex
5419         If forward Then
5420             idx += 1
5421             If idx > ListTab.TabPages.Count - 1 Then idx = 0
5422         Else
5423             idx -= 1
5424             If idx < 0 Then idx = ListTab.TabPages.Count - 1
5425         End If
5426         ListTab.SelectedIndex = idx
5427         ListTabSelect(ListTab.TabPages(idx))
5428     End Sub
5429
5430     Private Sub CopyStot()
5431         Dim clstr As String = ""
5432         Dim sb As New StringBuilder()
5433         Dim IsProtected As Boolean = False
5434         Dim isDm As Boolean = False
5435         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
5436         For Each idx As Integer In _curList.SelectedIndices
5437             Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
5438             If post.IsProtect Then
5439                 IsProtected = True
5440                 Continue For
5441             End If
5442             If post.IsDeleted Then Continue For
5443             If Not isDm Then
5444                 If post.RetweetedId > 0 Then
5445                     sb.AppendFormat("{0}:{1} [http://twitter.com/{0}/status/{2}]{3}", post.ScreenName, post.TextFromApi, post.RetweetedId, Environment.NewLine)
5446                 Else
5447                     sb.AppendFormat("{0}:{1} [http://twitter.com/{0}/status/{2}]{3}", post.ScreenName, post.TextFromApi, post.StatusId, Environment.NewLine)
5448                 End If
5449             Else
5450                 sb.AppendFormat("{0}:{1} [{2}]{3}", post.ScreenName, post.TextFromApi, post.StatusId, Environment.NewLine)
5451             End If
5452         Next
5453         If IsProtected Then
5454             MessageBox.Show(My.Resources.CopyStotText1)
5455         End If
5456         If sb.Length > 0 Then
5457             clstr = sb.ToString()
5458             Try
5459                 Clipboard.SetDataObject(clstr, False, 5, 100)
5460             Catch ex As Exception
5461                 MessageBox.Show(ex.Message)
5462             End Try
5463         End If
5464     End Sub
5465
5466     Private Sub CopyIdUri()
5467         Dim clstr As String = ""
5468         Dim sb As New StringBuilder()
5469         If Me._curTab Is Nothing Then Exit Sub
5470         If Me._statuses.GetTabByName(Me._curTab.Text) Is Nothing Then Exit Sub
5471         If Me._statuses.GetTabByName(Me._curTab.Text).TabType = TabUsageType.DirectMessage Then Exit Sub
5472         For Each idx As Integer In _curList.SelectedIndices
5473             Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
5474             If post.RetweetedId > 0 Then
5475                 sb.AppendFormat("http://twitter.com/{0}/status/{1}{2}", post.ScreenName, post.RetweetedId, Environment.NewLine)
5476             Else
5477                 sb.AppendFormat("http://twitter.com/{0}/status/{1}{2}", post.ScreenName, post.StatusId, Environment.NewLine)
5478             End If
5479         Next
5480         If sb.Length > 0 Then
5481             clstr = sb.ToString()
5482             Try
5483                 Clipboard.SetDataObject(clstr, False, 5, 100)
5484             Catch ex As Exception
5485                 MessageBox.Show(ex.Message)
5486             End Try
5487         End If
5488     End Sub
5489
5490     Private Sub GoFav(ByVal forward As Boolean)
5491         If _curList.VirtualListSize = 0 Then Exit Sub
5492         Dim fIdx As Integer = 0
5493         Dim toIdx As Integer = 0
5494         Dim stp As Integer = 1
5495
5496         If forward Then
5497             If _curList.SelectedIndices.Count = 0 Then
5498                 fIdx = 0
5499             Else
5500                 fIdx = _curList.SelectedIndices(0) + 1
5501                 If fIdx > _curList.VirtualListSize - 1 Then Exit Sub
5502             End If
5503             toIdx = _curList.VirtualListSize - 1
5504             stp = 1
5505         Else
5506             If _curList.SelectedIndices.Count = 0 Then
5507                 fIdx = _curList.VirtualListSize - 1
5508             Else
5509                 fIdx = _curList.SelectedIndices(0) - 1
5510                 If fIdx < 0 Then Exit Sub
5511             End If
5512             toIdx = 0
5513             stp = -1
5514         End If
5515
5516         For idx As Integer = fIdx To toIdx Step stp
5517             If _statuses.Item(_curTab.Text, idx).IsFav Then
5518                 SelectListItem(_curList, idx)
5519                 _curList.EnsureVisible(idx)
5520                 Exit For
5521             End If
5522         Next
5523     End Sub
5524
5525     Private Sub GoSamePostToAnotherTab(ByVal left As Boolean)
5526         If _curList.VirtualListSize = 0 Then Exit Sub
5527         Dim fIdx As Integer = 0
5528         Dim toIdx As Integer = 0
5529         Dim stp As Integer = 1
5530         Dim targetId As Long = 0
5531
5532         If _statuses.Tabs(_curTab.Text).TabType = TabUsageType.DirectMessage Then Exit Sub ' Directタブは対象外(見つかるはずがない)
5533         If _curList.SelectedIndices.Count = 0 Then Exit Sub '未選択も処理しない
5534
5535         targetId = GetCurTabPost(_curList.SelectedIndices(0)).StatusId
5536
5537         If left Then
5538             ' 左のタブへ
5539             If ListTab.SelectedIndex = 0 Then
5540                 Exit Sub
5541             Else
5542                 fIdx = ListTab.SelectedIndex - 1
5543             End If
5544             toIdx = 0
5545             stp = -1
5546         Else
5547             ' 右のタブへ
5548             If ListTab.SelectedIndex = ListTab.TabCount - 1 Then
5549                 Exit Sub
5550             Else
5551                 fIdx = ListTab.SelectedIndex + 1
5552             End If
5553             toIdx = ListTab.TabCount - 1
5554             stp = 1
5555         End If
5556
5557         Dim found As Boolean = False
5558         For tabidx As Integer = fIdx To toIdx Step stp
5559             If _statuses.Tabs(ListTab.TabPages(tabidx).Text).TabType = TabUsageType.DirectMessage Then Continue For ' Directタブは対象外
5560             For idx As Integer = 0 To DirectCast(ListTab.TabPages(tabidx).Tag, DetailsListView).VirtualListSize - 1
5561                 If _statuses.Item(ListTab.TabPages(tabidx).Text, idx).StatusId = targetId Then
5562                     ListTab.SelectedIndex = tabidx
5563                     ListTabSelect(ListTab.TabPages(tabidx))
5564                     SelectListItem(_curList, idx)
5565                     _curList.EnsureVisible(idx)
5566                     found = True
5567                     Exit For
5568                 End If
5569             Next
5570             If found Then Exit For
5571         Next
5572     End Sub
5573
5574     Private Sub GoPost(ByVal forward As Boolean)
5575         If _curList.SelectedIndices.Count = 0 OrElse _curPost Is Nothing Then Exit Sub
5576         Dim fIdx As Integer = 0
5577         Dim toIdx As Integer = 0
5578         Dim stp As Integer = 1
5579
5580         If forward Then
5581             fIdx = _curList.SelectedIndices(0) + 1
5582             If fIdx > _curList.VirtualListSize - 1 Then Exit Sub
5583             toIdx = _curList.VirtualListSize - 1
5584             stp = 1
5585         Else
5586             fIdx = _curList.SelectedIndices(0) - 1
5587             If fIdx < 0 Then Exit Sub
5588             toIdx = 0
5589             stp = -1
5590         End If
5591
5592         Dim name As String = ""
5593         If _curPost.RetweetedId = 0 Then
5594             name = _curPost.ScreenName
5595         Else
5596             name = _curPost.RetweetedBy
5597         End If
5598         For idx As Integer = fIdx To toIdx Step stp
5599             If _statuses.Item(_curTab.Text, idx).RetweetedId = 0 Then
5600                 If _statuses.Item(_curTab.Text, idx).ScreenName = name Then
5601                     SelectListItem(_curList, idx)
5602                     _curList.EnsureVisible(idx)
5603                     Exit For
5604                 End If
5605             Else
5606                 If _statuses.Item(_curTab.Text, idx).RetweetedBy = name Then
5607                     SelectListItem(_curList, idx)
5608                     _curList.EnsureVisible(idx)
5609                     Exit For
5610                 End If
5611             End If
5612         Next
5613     End Sub
5614
5615     Private Sub GoRelPost(ByVal forward As Boolean)
5616         If _curList.SelectedIndices.Count = 0 Then Exit Sub
5617
5618         Dim fIdx As Integer = 0
5619         Dim toIdx As Integer = 0
5620         Dim stp As Integer = 1
5621         If forward Then
5622             fIdx = _curList.SelectedIndices(0) + 1
5623             If fIdx > _curList.VirtualListSize - 1 Then Exit Sub
5624             toIdx = _curList.VirtualListSize - 1
5625             stp = 1
5626         Else
5627             fIdx = _curList.SelectedIndices(0) - 1
5628             If fIdx < 0 Then Exit Sub
5629             toIdx = 0
5630             stp = -1
5631         End If
5632
5633         If Not _anchorFlag Then
5634             If _curPost Is Nothing Then Exit Sub
5635             _anchorPost = _curPost
5636             _anchorFlag = True
5637         Else
5638             If _anchorPost Is Nothing Then Exit Sub
5639         End If
5640
5641         For idx As Integer = fIdx To toIdx Step stp
5642             Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
5643             If post.ScreenName = _anchorPost.ScreenName OrElse _
5644                post.RetweetedBy = _anchorPost.ScreenName OrElse _
5645                post.ScreenName = _anchorPost.RetweetedBy OrElse _
5646                (Not String.IsNullOrEmpty(post.RetweetedBy) AndAlso post.RetweetedBy = _anchorPost.RetweetedBy) OrElse _
5647                _anchorPost.ReplyToList.Contains(post.ScreenName.ToLower()) OrElse _
5648                _anchorPost.ReplyToList.Contains(post.RetweetedBy.ToLower()) OrElse _
5649                post.ReplyToList.Contains(_anchorPost.ScreenName.ToLower()) OrElse _
5650                post.ReplyToList.Contains(_anchorPost.RetweetedBy.ToLower()) Then
5651                 SelectListItem(_curList, idx)
5652                 _curList.EnsureVisible(idx)
5653                 Exit For
5654             End If
5655         Next
5656     End Sub
5657
5658     Private Sub GoAnchor()
5659         If _anchorPost Is Nothing Then Exit Sub
5660         Dim idx As Integer = _statuses.Tabs(_curTab.Text).IndexOf(_anchorPost.StatusId)
5661         If idx = -1 Then Exit Sub
5662
5663         SelectListItem(_curList, idx)
5664         _curList.EnsureVisible(idx)
5665     End Sub
5666
5667     Private Sub GoTopEnd(ByVal GoTop As Boolean)
5668         Dim _item As ListViewItem
5669         Dim idx As Integer
5670
5671         If GoTop Then
5672             _item = _curList.GetItemAt(0, 25)
5673             If _item Is Nothing Then
5674                 idx = 0
5675             Else
5676                 idx = _item.Index
5677             End If
5678         Else
5679             _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1)
5680             If _item Is Nothing Then
5681                 idx = _curList.VirtualListSize - 1
5682             Else
5683                 idx = _item.Index
5684             End If
5685         End If
5686         SelectListItem(_curList, idx)
5687     End Sub
5688
5689     Private Sub GoMiddle()
5690         Dim _item As ListViewItem
5691         Dim idx1 As Integer
5692         Dim idx2 As Integer
5693         Dim idx3 As Integer
5694
5695         _item = _curList.GetItemAt(0, 0)
5696         If _item Is Nothing Then
5697             idx1 = 0
5698         Else
5699             idx1 = _item.Index
5700         End If
5701         _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1)
5702         If _item Is Nothing Then
5703             idx2 = _curList.VirtualListSize - 1
5704         Else
5705             idx2 = _item.Index
5706         End If
5707         idx3 = (idx1 + idx2) \ 2
5708
5709         SelectListItem(_curList, idx3)
5710     End Sub
5711
5712     Private Sub GoLast()
5713         If _curList.VirtualListSize = 0 Then Exit Sub
5714
5715         If _statuses.SortOrder = SortOrder.Ascending Then
5716             SelectListItem(_curList, _curList.VirtualListSize - 1)
5717             _curList.EnsureVisible(_curList.VirtualListSize - 1)
5718         Else
5719             SelectListItem(_curList, 0)
5720             _curList.EnsureVisible(0)
5721         End If
5722     End Sub
5723
5724     Private Sub MoveTop()
5725         If _curList.SelectedIndices.Count = 0 Then Exit Sub
5726         Dim idx As Integer = _curList.SelectedIndices(0)
5727         If _statuses.SortOrder = SortOrder.Ascending Then
5728             _curList.EnsureVisible(_curList.VirtualListSize - 1)
5729         Else
5730             _curList.EnsureVisible(0)
5731         End If
5732         _curList.EnsureVisible(idx)
5733     End Sub
5734
5735     Private Sub GoInReplyToPostTree()
5736         If _curPost Is Nothing Then Return
5737
5738         Dim curTabClass As TabClass = _statuses.Tabs(_curTab.Text)
5739
5740         If curTabClass.TabType = TabUsageType.PublicSearch AndAlso _curPost.InReplyToStatusId = 0 AndAlso _curPost.TextFromApi.Contains("@") Then
5741             Dim post As PostClass = Nothing
5742             Dim r As String = tw.GetStatusApi(False, _curPost.StatusId, post)
5743             If r = "" AndAlso post IsNot Nothing Then
5744                 _curPost.InReplyToStatusId = post.InReplyToStatusId
5745                 _curPost.InReplyToUser = post.InReplyToUser
5746                 _curPost.IsReply = post.IsReply
5747                 _itemCache = Nothing
5748                 _curList.RedrawItems(_curItemIndex, _curItemIndex, False)
5749             Else
5750                 Me.StatusLabel.Text = r
5751             End If
5752         End If
5753
5754         If Not (Me.ExistCurrentPost AndAlso _curPost.InReplyToUser IsNot Nothing AndAlso _curPost.InReplyToStatusId > 0) Then Return
5755
5756         If replyChains Is Nothing OrElse (replyChains.Count > 0 AndAlso replyChains.Peek().InReplyToId <> _curPost.StatusId) Then
5757             replyChains = New Stack(Of ReplyChain)
5758         End If
5759         replyChains.Push(New ReplyChain(_curPost.StatusId, _curPost.InReplyToStatusId, _curTab))
5760
5761         Dim inReplyToIndex As Integer
5762         Dim inReplyToTabName As String
5763         Dim inReplyToId As Long = _curPost.InReplyToStatusId
5764         Dim inReplyToUser As String = _curPost.InReplyToUser
5765         Dim curTabPosts As Dictionary(Of Long, PostClass)
5766
5767         If _statuses.Tabs(_curTab.Text).IsInnerStorageTabType Then
5768             curTabPosts = curTabClass.Posts
5769         Else
5770             curTabPosts = _statuses.Posts
5771         End If
5772
5773         Dim inReplyToPosts = From tab In _statuses.Tabs.Values
5774                              Order By tab IsNot curTabClass
5775                              From post In DirectCast(IIf(tab.IsInnerStorageTabType, tab.Posts, _statuses.Posts), Dictionary(Of Long, PostClass)).Values
5776                              Where post.StatusId = inReplyToId
5777                              Let index = tab.IndexOf(post.StatusId)
5778                              Where index <> -1
5779                              Select New With {.Tab = tab, .Index = index}
5780
5781         Try
5782             Dim inReplyPost = inReplyToPosts.First()
5783             inReplyToTabName = inReplyPost.Tab.TabName
5784             inReplyToIndex = inReplyPost.Index
5785         Catch ex As InvalidOperationException
5786             Dim post As PostClass = Nothing
5787             Dim r As String = tw.GetStatusApi(False, _curPost.InReplyToStatusId, post)
5788             If r = "" AndAlso post IsNot Nothing Then
5789                 post.IsRead = True
5790                 _statuses.AddPost(post)
5791                 _statuses.DistributePosts()
5792                 '_statuses.SubmitUpdate(Nothing, Nothing, Nothing, False)
5793                 Me.RefreshTimeline(False)
5794                 Try
5795                     Dim inReplyPost = inReplyToPosts.First()
5796                     inReplyToTabName = inReplyPost.Tab.TabName
5797                     inReplyToIndex = inReplyPost.Index
5798                 Catch ex2 As InvalidOperationException
5799                     OpenUriAsync("http://twitter.com/" + inReplyToUser + "/statuses/" + inReplyToId.ToString())
5800                     Exit Sub
5801                 End Try
5802             Else
5803                 Me.StatusLabel.Text = r
5804                 OpenUriAsync("http://twitter.com/" + inReplyToUser + "/statuses/" + inReplyToId.ToString())
5805                 Exit Sub
5806             End If
5807         End Try
5808
5809         Dim tabPage = Me.ListTab.TabPages.Cast(Of TabPage).First(Function(tp) tp.Text = inReplyToTabName)
5810         Dim listView = DirectCast(tabPage.Tag, DetailsListView)
5811
5812         If _curTab IsNot tabPage Then
5813             Me.ListTab.SelectTab(tabPage)
5814         End If
5815
5816         Me.SelectListItem(listView, inReplyToIndex)
5817         listView.EnsureVisible(inReplyToIndex)
5818     End Sub
5819
5820     Private Sub GoBackInReplyToPostTree(Optional ByVal parallel As Boolean = False, Optional ByVal isForward As Boolean = True)
5821         If _curPost Is Nothing Then Return
5822
5823         Dim curTabClass As TabClass = _statuses.Tabs(_curTab.Text)
5824         Dim curTabPosts As Dictionary(Of Long, PostClass) = DirectCast(IIf(curTabClass.IsInnerStorageTabType, curTabClass.Posts, _statuses.Posts), Dictionary(Of Long, PostClass))
5825
5826         If parallel Then
5827             If _curPost.InReplyToStatusId <> 0 Then
5828                 Dim posts = From t In _statuses.Tabs
5829                             From p In DirectCast(IIf(t.Value.IsInnerStorageTabType, t.Value.Posts, _statuses.Posts), Dictionary(Of Long, PostClass))
5830                             Where p.Value.StatusId <> _curPost.StatusId AndAlso p.Value.InReplyToStatusId = _curPost.InReplyToStatusId
5831                             Let indexOf = t.Value.IndexOf(p.Value.StatusId)
5832                             Where indexOf > -1
5833                             Order By IIf(isForward, indexOf, indexOf * -1)
5834                             Order By t.Value IsNot curTabClass
5835                             Select New With {.Tab = t.Value, .Post = p.Value, .Index = indexOf}
5836                 Try
5837                     Dim postList = posts.ToList()
5838                     For i As Integer = postList.Count - 1 To 0 Step -1
5839                         Dim index As Integer = i
5840                         If postList.FindIndex(Function(pst) pst.Post.StatusId = postList(index).Post.StatusId) <> index Then
5841                             postList.RemoveAt(index)
5842                         End If
5843                     Next
5844                     Dim post = postList.FirstOrDefault(Function(pst) pst.Tab Is curTabClass AndAlso DirectCast(IIf(isForward, pst.Index > _curItemIndex, pst.Index < _curItemIndex), Boolean))
5845                     If post Is Nothing Then post = postList.FirstOrDefault(Function(pst) pst.Tab IsNot curTabClass)
5846                     If post Is Nothing Then post = postList.First()
5847                     Me.ListTab.SelectTab(Me.ListTab.TabPages.Cast(Of TabPage).First(Function(tp) tp.Text = post.Tab.TabName))
5848                     Dim listView = DirectCast(Me.ListTab.SelectedTab.Tag, DetailsListView)
5849                     SelectListItem(listView, post.Index)
5850                     listView.EnsureVisible(post.Index)
5851                 Catch ex As InvalidOperationException
5852                     Exit Sub
5853                 End Try
5854             End If
5855         Else
5856             If replyChains Is Nothing OrElse replyChains.Count < 1 Then
5857                 Dim posts = From t In _statuses.Tabs
5858                             From p In DirectCast(IIf(t.Value.IsInnerStorageTabType, t.Value.Posts, _statuses.Posts), Dictionary(Of Long, PostClass))
5859                             Where p.Value.InReplyToStatusId = _curPost.StatusId
5860                             Let indexOf = t.Value.IndexOf(p.Value.StatusId)
5861                             Where indexOf > -1
5862                             Order By indexOf
5863                             Order By t.Value IsNot curTabClass
5864                             Select New With {.Tab = t.Value, .Index = indexOf}
5865                 Try
5866                     Dim post = posts.First()
5867                     Me.ListTab.SelectTab(Me.ListTab.TabPages.Cast(Of TabPage).First(Function(tp) tp.Text = post.Tab.TabName))
5868                     Dim listView = DirectCast(Me.ListTab.SelectedTab.Tag, DetailsListView)
5869                     SelectListItem(listView, post.Index)
5870                     listView.EnsureVisible(post.Index)
5871                 Catch ex As InvalidOperationException
5872                     Exit Sub
5873                 End Try
5874             Else
5875                 Dim chainHead As ReplyChain = replyChains.Pop()
5876                 If chainHead.InReplyToId = _curPost.StatusId Then
5877                     Dim idx As Integer = _statuses.Tabs(chainHead.OriginalTab.Text).IndexOf(chainHead.OriginalId)
5878                     If idx = -1 Then
5879                         replyChains = Nothing
5880                     Else
5881                         Try
5882                             ListTab.SelectTab(chainHead.OriginalTab)
5883                         Catch ex As Exception
5884                             replyChains = Nothing
5885                         End Try
5886                         SelectListItem(_curList, idx)
5887                         _curList.EnsureVisible(idx)
5888                     End If
5889                 Else
5890                     replyChains = Nothing
5891                     Me.GoBackInReplyToPostTree(parallel)
5892                 End If
5893             End If
5894         End If
5895     End Sub
5896
5897     Private Sub MyList_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
5898         _anchorFlag = False
5899     End Sub
5900
5901     Private Sub StatusText_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusText.Enter
5902         ' フォーカスの戻り先を StatusText に設定
5903         Me.Tag = StatusText
5904         StatusText.BackColor = _clInputBackcolor
5905     End Sub
5906
5907     Public Property InputBackColor() As System.Drawing.Color
5908         Get
5909             Return _clInputBackcolor
5910         End Get
5911         Set(ByVal value As System.Drawing.Color)
5912             _clInputBackcolor = value
5913         End Set
5914     End Property
5915
5916     Private Sub StatusText_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusText.Leave
5917         ' フォーカスがメニューに遷移しないならばフォーカスはタブに移ることを期待
5918         If ListTab.SelectedTab IsNot Nothing AndAlso MenuStrip1.Tag Is Nothing Then Me.Tag = ListTab.SelectedTab.Tag
5919         StatusText.BackColor = Color.FromKnownColor(KnownColor.Window)
5920     End Sub
5921
5922     Private Sub StatusText_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles StatusText.KeyDown
5923         Dim State As ModifierState = GetModifierState(e.Control, e.Shift, e.Alt)
5924         If State = ModifierState.NotFlags Then Exit Sub
5925         If CommonKeyDown(e.KeyCode, FocusedControl.StatusText, State) Then
5926             e.Handled = True
5927             e.SuppressKeyPress = True
5928         End If
5929
5930         Me.StatusText_TextChanged(Nothing, Nothing)
5931     End Sub
5932
5933     Private Sub SaveConfigsAll(ByVal ifModified As Boolean)
5934         If Not ifModified Then
5935             SaveConfigsCommon()
5936             SaveConfigsLocal()
5937             'SaveConfigsTab(True)    'True:事前に設定ファイル削除
5938             SaveConfigsTabs()
5939         Else
5940             If _modifySettingCommon Then SaveConfigsCommon()
5941             If _modifySettingLocal Then SaveConfigsLocal()
5942             If _modifySettingAtId AndAlso SettingDialog.UseAtIdSupplement AndAlso AtIdSupl IsNot Nothing Then
5943                 _modifySettingAtId = False
5944                 Dim cfgAtId As New SettingAtIdList(AtIdSupl.GetItemList)
5945                 cfgAtId.Save()
5946             End If
5947         End If
5948     End Sub
5949
5950     Private Sub SaveConfigsCommon()
5951         If _ignoreConfigSave Then Exit Sub
5952
5953         _modifySettingCommon = False
5954         SyncLock _syncObject
5955             _cfgCommon.UserName = tw.Username
5956             _cfgCommon.Password = tw.Password
5957             _cfgCommon.IsOAuth = SettingDialog.IsOAuth
5958             _cfgCommon.Token = tw.AccessToken
5959             _cfgCommon.TokenSecret = tw.AccessTokenSecret
5960             _cfgCommon.UserstreamStartup = SettingDialog.UserstreamStartup
5961             _cfgCommon.UserstreamPeriod = SettingDialog.UserstreamPeriodInt
5962             _cfgCommon.TimelinePeriod = SettingDialog.TimelinePeriodInt
5963             _cfgCommon.ReplyPeriod = SettingDialog.ReplyPeriodInt
5964             _cfgCommon.DMPeriod = SettingDialog.DMPeriodInt
5965             _cfgCommon.PubSearchPeriod = SettingDialog.PubSearchPeriodInt
5966             _cfgCommon.ListsPeriod = SettingDialog.ListsPeriodInt
5967             _cfgCommon.UserTimelinePeriod = SettingDialog.UserTimelinePeriodInt
5968             _cfgCommon.Read = SettingDialog.Readed
5969             _cfgCommon.IconSize = SettingDialog.IconSz
5970             _cfgCommon.UnreadManage = SettingDialog.UnreadManage
5971             _cfgCommon.PlaySound = SettingDialog.PlaySound
5972             _cfgCommon.OneWayLove = SettingDialog.OneWayLove
5973
5974             _cfgCommon.NameBalloon = SettingDialog.NameBalloon
5975             _cfgCommon.PostCtrlEnter = SettingDialog.PostCtrlEnter
5976             _cfgCommon.PostShiftEnter = SettingDialog.PostShiftEnter
5977             _cfgCommon.CountApi = SettingDialog.CountApi
5978             _cfgCommon.CountApiReply = SettingDialog.CountApiReply
5979             _cfgCommon.PostAndGet = SettingDialog.PostAndGet
5980             _cfgCommon.DispUsername = SettingDialog.DispUsername
5981             _cfgCommon.MinimizeToTray = SettingDialog.MinimizeToTray
5982             _cfgCommon.CloseToExit = SettingDialog.CloseToExit
5983             _cfgCommon.DispLatestPost = SettingDialog.DispLatestPost
5984             _cfgCommon.SortOrderLock = SettingDialog.SortOrderLock
5985             _cfgCommon.TinyUrlResolve = SettingDialog.TinyUrlResolve
5986             _cfgCommon.PeriodAdjust = SettingDialog.PeriodAdjust
5987             _cfgCommon.StartupVersion = SettingDialog.StartupVersion
5988             _cfgCommon.StartupFollowers = SettingDialog.StartupFollowers
5989             _cfgCommon.RestrictFavCheck = SettingDialog.RestrictFavCheck
5990             _cfgCommon.AlwaysTop = SettingDialog.AlwaysTop
5991             _cfgCommon.UrlConvertAuto = SettingDialog.UrlConvertAuto
5992             _cfgCommon.Outputz = SettingDialog.OutputzEnabled
5993             _cfgCommon.OutputzKey = SettingDialog.OutputzKey
5994             _cfgCommon.OutputzUrlMode = SettingDialog.OutputzUrlmode
5995             _cfgCommon.UseUnreadStyle = SettingDialog.UseUnreadStyle
5996             _cfgCommon.DateTimeFormat = SettingDialog.DateTimeFormat
5997             _cfgCommon.DefaultTimeOut = SettingDialog.DefaultTimeOut
5998             _cfgCommon.RetweetNoConfirm = SettingDialog.RetweetNoConfirm
5999             _cfgCommon.LimitBalloon = SettingDialog.LimitBalloon
6000             _cfgCommon.EventNotifyEnabled = SettingDialog.EventNotifyEnabled
6001             _cfgCommon.EventNotifyFlag = SettingDialog.EventNotifyFlag
6002             _cfgCommon.IsMyEventNotifyFlag = SettingDialog.IsMyEventNotifyFlag
6003             _cfgCommon.ForceEventNotify = SettingDialog.ForceEventNotify
6004             _cfgCommon.FavEventUnread = SettingDialog.FavEventUnread
6005             _cfgCommon.TranslateLanguage = SettingDialog.TranslateLanguage
6006             _cfgCommon.EventSoundFile = SettingDialog.EventSoundFile
6007             _cfgCommon.AutoShortUrlFirst = SettingDialog.AutoShortUrlFirst
6008             _cfgCommon.TabIconDisp = SettingDialog.TabIconDisp
6009             _cfgCommon.ReplyIconState = SettingDialog.ReplyIconState
6010             _cfgCommon.ReadOwnPost = SettingDialog.ReadOwnPost
6011             _cfgCommon.GetFav = SettingDialog.GetFav
6012             _cfgCommon.IsMonospace = SettingDialog.IsMonospace
6013             If IdeographicSpaceToSpaceToolStripMenuItem IsNot Nothing AndAlso _
6014                IdeographicSpaceToSpaceToolStripMenuItem.IsDisposed = False Then
6015                 _cfgCommon.WideSpaceConvert = Me.IdeographicSpaceToSpaceToolStripMenuItem.Checked
6016             End If
6017             _cfgCommon.ReadOldPosts = SettingDialog.ReadOldPosts
6018             _cfgCommon.UseSsl = SettingDialog.UseSsl
6019             _cfgCommon.BilyUser = SettingDialog.BitlyUser
6020             _cfgCommon.BitlyPwd = SettingDialog.BitlyPwd
6021             _cfgCommon.ShowGrid = SettingDialog.ShowGrid
6022             _cfgCommon.UseAtIdSupplement = SettingDialog.UseAtIdSupplement
6023             _cfgCommon.UseHashSupplement = SettingDialog.UseHashSupplement
6024             _cfgCommon.PreviewEnable = SettingDialog.PreviewEnable
6025             _cfgCommon.Language = SettingDialog.Language
6026
6027             _cfgCommon.SortOrder = _statuses.SortOrder
6028             Select Case _statuses.SortMode
6029                 Case IdComparerClass.ComparerMode.Nickname  'ニックネーム
6030                     _cfgCommon.SortColumn = 1
6031                 Case IdComparerClass.ComparerMode.Data  '本文
6032                     _cfgCommon.SortColumn = 2
6033                 Case IdComparerClass.ComparerMode.Id  '時刻=発言Id
6034                     _cfgCommon.SortColumn = 3
6035                 Case IdComparerClass.ComparerMode.Name  '名前
6036                     _cfgCommon.SortColumn = 4
6037                 Case IdComparerClass.ComparerMode.Source  'Source
6038                     _cfgCommon.SortColumn = 7
6039             End Select
6040
6041             _cfgCommon.Nicoms = SettingDialog.Nicoms
6042             _cfgCommon.HashTags = HashMgr.HashHistories
6043             If HashMgr.IsPermanent Then
6044                 _cfgCommon.HashSelected = HashMgr.UseHash
6045             Else
6046                 _cfgCommon.HashSelected = ""
6047             End If
6048             _cfgCommon.HashIsHead = HashMgr.IsHead
6049             _cfgCommon.HashIsPermanent = HashMgr.IsPermanent
6050             _cfgCommon.TwitterUrl = SettingDialog.TwitterApiUrl
6051             _cfgCommon.TwitterSearchUrl = SettingDialog.TwitterSearchApiUrl
6052             _cfgCommon.HotkeyEnabled = SettingDialog.HotkeyEnabled
6053             _cfgCommon.HotkeyModifier = SettingDialog.HotkeyMod
6054             _cfgCommon.HotkeyKey = SettingDialog.HotkeyKey
6055             _cfgCommon.HotkeyValue = SettingDialog.HotkeyValue
6056             _cfgCommon.BlinkNewMentions = SettingDialog.BlinkNewMentions
6057             If ToolStripFocusLockMenuItem IsNot Nothing AndAlso _
6058                     ToolStripFocusLockMenuItem.IsDisposed = False Then
6059                 _cfgCommon.FocusLockToStatusText = Me.ToolStripFocusLockMenuItem.Checked
6060             End If
6061             _cfgCommon.UseAdditionalCount = SettingDialog.UseAdditionalCount
6062             _cfgCommon.MoreCountApi = SettingDialog.MoreCountApi
6063             _cfgCommon.FirstCountApi = SettingDialog.FirstCountApi
6064             _cfgCommon.SearchCountApi = SettingDialog.SearchCountApi
6065             _cfgCommon.FavoritesCountApi = SettingDialog.FavoritesCountApi
6066             _cfgCommon.UserTimelineCountApi = SettingDialog.UserTimelineCountApi
6067             _cfgCommon.TrackWord = tw.TrackWord
6068             _cfgCommon.AllAtReply = tw.AllAtReply
6069             _cfgCommon.OpenUserTimeline = SettingDialog.OpenUserTimeline
6070             _cfgCommon.ListCountApi = SettingDialog.ListCountApi
6071             _cfgCommon.UseImageService = ImageServiceCombo.SelectedIndex
6072
6073             _cfgCommon.Save()
6074         End SyncLock
6075     End Sub
6076
6077     Private Sub SaveConfigsLocal()
6078         If _ignoreConfigSave Then Exit Sub
6079         SyncLock _syncObject
6080             _modifySettingLocal = False
6081             _cfgLocal.FormSize = _mySize
6082             _cfgLocal.FormLocation = _myLoc
6083             _cfgLocal.SplitterDistance = _mySpDis
6084             _cfgLocal.PreviewDistance = _mySpDis3
6085             _cfgLocal.StatusMultiline = StatusText.Multiline
6086             _cfgLocal.StatusTextHeight = _mySpDis2
6087             _cfgLocal.StatusText = SettingDialog.Status
6088
6089             _cfgLocal.FontUnread = _fntUnread
6090             _cfgLocal.ColorUnread = _clUnread
6091             _cfgLocal.FontRead = _fntReaded
6092             _cfgLocal.ColorRead = _clReaded
6093             _cfgLocal.FontDetail = _fntDetail
6094             _cfgLocal.ColorDetail = _clDetail
6095             _cfgLocal.ColorDetailBackcolor = _clDetailBackcolor
6096             _cfgLocal.ColorDetailLink = _clDetailLink
6097             _cfgLocal.ColorFav = _clFav
6098             _cfgLocal.ColorOWL = _clOWL
6099             _cfgLocal.ColorRetweet = _clRetweet
6100             _cfgLocal.ColorSelf = _clSelf
6101             _cfgLocal.ColorAtSelf = _clAtSelf
6102             _cfgLocal.ColorTarget = _clTarget
6103             _cfgLocal.ColorAtTarget = _clAtTarget
6104             _cfgLocal.ColorAtFromTarget = _clAtFromTarget
6105             _cfgLocal.ColorAtTo = _clAtTo
6106             _cfgLocal.ColorListBackcolor = _clListBackcolor
6107             _cfgLocal.ColorInputBackcolor = _clInputBackcolor
6108             _cfgLocal.ColorInputFont = _clInputFont
6109             _cfgLocal.FontInputFont = _fntInputFont
6110
6111             _cfgLocal.BrowserPath = SettingDialog.BrowserPath
6112             _cfgLocal.UseRecommendStatus = SettingDialog.UseRecommendStatus
6113             _cfgLocal.ProxyType = SettingDialog.SelectedProxyType
6114             _cfgLocal.ProxyAddress = SettingDialog.ProxyAddress
6115             _cfgLocal.ProxyPort = SettingDialog.ProxyPort
6116             _cfgLocal.ProxyUser = SettingDialog.ProxyUser
6117             _cfgLocal.ProxyPassword = SettingDialog.ProxyPassword
6118             If _ignoreConfigSave Then Exit Sub
6119             _cfgLocal.Save()
6120         End SyncLock
6121     End Sub
6122
6123     Private Sub SaveConfigsTabs()
6124         Dim tabSetting As New SettingTabs
6125         For i As Integer = 0 To ListTab.TabPages.Count - 1
6126             If _statuses.Tabs(ListTab.TabPages(i).Text).TabType <> TabUsageType.Related Then tabSetting.Tabs.Add(_statuses.Tabs(ListTab.TabPages(i).Text))
6127         Next
6128         tabSetting.Save()
6129     End Sub
6130
6131     Private Sub SaveLogMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveLogMenuItem.Click, SaveFileMenuItem.Click
6132         Dim rslt As DialogResult = MessageBox.Show(String.Format(My.Resources.SaveLogMenuItem_ClickText1, Environment.NewLine), _
6133                 My.Resources.SaveLogMenuItem_ClickText2, _
6134                 MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)
6135         If rslt = Windows.Forms.DialogResult.Cancel Then Exit Sub
6136
6137         SaveFileDialog1.FileName = "TweenPosts" + Format(Now, "yyMMdd-HHmmss") + ".tsv"
6138         SaveFileDialog1.InitialDirectory = My.Application.Info.DirectoryPath
6139         SaveFileDialog1.Filter = My.Resources.SaveLogMenuItem_ClickText3
6140         SaveFileDialog1.FilterIndex = 0
6141         SaveFileDialog1.Title = My.Resources.SaveLogMenuItem_ClickText4
6142         SaveFileDialog1.RestoreDirectory = True
6143
6144         If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
6145             If Not SaveFileDialog1.ValidateNames Then Exit Sub
6146             Using sw As StreamWriter = New StreamWriter(SaveFileDialog1.FileName, False, Encoding.UTF8)
6147                 If rslt = Windows.Forms.DialogResult.Yes Then
6148                     'All
6149                     For idx As Integer = 0 To _curList.VirtualListSize - 1
6150                         Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
6151                         Dim protect As String = ""
6152                         If post.IsProtect Then protect = "Protect"
6153                         sw.WriteLine(post.Nickname & vbTab & _
6154                                  """" & post.TextFromApi.Replace(vbLf, "").Replace("""", """""") + """" & vbTab & _
6155                                  post.CreatedAt.ToString() & vbTab & _
6156                                  post.ScreenName & vbTab & _
6157                                  post.StatusId.ToString() & vbTab & _
6158                                  post.ImageUrl & vbTab & _
6159                                  """" & post.Text.Replace(vbLf, "").Replace("""", """""") + """" & vbTab & _
6160                                  protect)
6161                     Next
6162                 Else
6163                     For Each idx As Integer In _curList.SelectedIndices
6164                         Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
6165                         Dim protect As String = ""
6166                         If post.IsProtect Then protect = "Protect"
6167                         sw.WriteLine(post.Nickname & vbTab & _
6168                                  """" & post.TextFromApi.Replace(vbLf, "").Replace("""", """""") + """" & vbTab & _
6169                                  post.CreatedAt.ToString() & vbTab & _
6170                                  post.ScreenName & vbTab & _
6171                                  post.StatusId.ToString() & vbTab & _
6172                                  post.ImageUrl & vbTab & _
6173                                  """" & post.Text.Replace(vbLf, "").Replace("""", """""") + """" & vbTab & _
6174                                  protect)
6175                     Next
6176                 End If
6177                 sw.Close()
6178                 sw.Dispose()
6179             End Using
6180         End If
6181         Me.TopMost = SettingDialog.AlwaysTop
6182     End Sub
6183
6184     Private Sub PostBrowser_PreviewKeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles PostBrowser.PreviewKeyDown
6185         Dim State As ModifierState = GetModifierState(e.Control, e.Shift, e.Alt)
6186         If State = ModifierState.NotFlags Then Exit Sub
6187         Dim KeyRes As Boolean = CommonKeyDown(e.KeyCode, FocusedControl.PostBrowser, State)
6188         If KeyRes Then
6189             e.IsInputKey = True
6190         End If
6191     End Sub
6192     Public Function TabRename(ByRef tabName As String) As Boolean
6193         'タブ名変更
6194         Dim newTabText As String = Nothing
6195         Using inputName As New InputTabName()
6196             inputName.TabName = tabName
6197             inputName.ShowDialog()
6198             If inputName.DialogResult = Windows.Forms.DialogResult.Cancel Then Return False
6199             newTabText = inputName.TabName
6200             inputName.Dispose()
6201         End Using
6202         Me.TopMost = SettingDialog.AlwaysTop
6203         If Not String.IsNullOrEmpty(newTabText) Then
6204             '新タブ名存在チェック
6205             For i As Integer = 0 To ListTab.TabCount - 1
6206                 If ListTab.TabPages(i).Text = newTabText Then
6207                     Dim tmp As String = String.Format(My.Resources.Tabs_DoubleClickText1, newTabText)
6208                     MessageBox.Show(tmp, My.Resources.Tabs_DoubleClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
6209                     Return False
6210                 End If
6211             Next
6212             'タブ名のリスト作り直し(デフォルトタブ以外は再作成)
6213             For i As Integer = 0 To ListTab.TabCount - 1
6214                 If _statuses.IsDistributableTab(ListTab.TabPages(i).Text) Then
6215                     TabDialog.RemoveTab(ListTab.TabPages(i).Text)
6216                 End If
6217                 If ListTab.TabPages(i).Text = tabName Then
6218                     ListTab.TabPages(i).Text = newTabText
6219                 End If
6220             Next
6221             _statuses.RenameTab(tabName, newTabText)
6222
6223             For i As Integer = 0 To ListTab.TabCount - 1
6224                 If _statuses.IsDistributableTab(ListTab.TabPages(i).Text) Then
6225                     If ListTab.TabPages(i).Text = tabName Then
6226                         ListTab.TabPages(i).Text = newTabText
6227                     End If
6228                     TabDialog.AddTab(ListTab.TabPages(i).Text)
6229                 End If
6230             Next
6231             SaveConfigsCommon()
6232             SaveConfigsTabs()
6233             _rclickTabName = newTabText
6234             tabName = newTabText
6235             Return True
6236         Else
6237             Return False
6238         End If
6239     End Function
6240
6241     Private Sub ListTab_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseClick
6242         If e.Button = Windows.Forms.MouseButtons.Middle Then
6243             For i As Integer = 0 To Me.ListTab.TabPages.Count - 1
6244                 If Me.ListTab.GetTabRect(i).Contains(e.Location) Then
6245                     Me.RemoveSpecifiedTab(Me.ListTab.TabPages(i).Text, True)
6246                     Me.SaveConfigsTabs()
6247                     Exit For
6248                 End If
6249             Next
6250         End If
6251     End Sub
6252
6253     Private Sub Tabs_DoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseDoubleClick
6254         Dim tn As String = ListTab.SelectedTab.Text
6255         TabRename(tn)
6256     End Sub
6257
6258     Private Sub Tabs_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseDown
6259         Dim cpos As New Point(e.X, e.Y)
6260         If e.Button = Windows.Forms.MouseButtons.Left Then
6261             For i As Integer = 0 To ListTab.TabPages.Count - 1
6262                 If Me.ListTab.GetTabRect(i).Contains(e.Location) Then
6263                     _tabDrag = True
6264                     _tabMouseDownPoint = e.Location
6265                     Exit For
6266                 End If
6267             Next
6268         Else
6269             _tabDrag = False
6270         End If
6271     End Sub
6272
6273     Private Sub Tabs_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListTab.DragEnter
6274         If e.Data.GetDataPresent(GetType(TabPage)) Then
6275             e.Effect = DragDropEffects.Move
6276         Else
6277             e.Effect = DragDropEffects.None
6278         End If
6279     End Sub
6280
6281     Private Sub Tabs_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListTab.DragDrop
6282         If Not e.Data.GetDataPresent(GetType(TabPage)) Then Exit Sub
6283
6284         _tabDrag = False
6285         Dim tn As String = ""
6286         Dim bef As Boolean
6287         Dim cpos As New Point(e.X, e.Y)
6288         Dim spos As Point = ListTab.PointToClient(cpos)
6289         Dim i As Integer
6290         For i = 0 To ListTab.TabPages.Count - 1
6291             Dim rect As Rectangle = ListTab.GetTabRect(i)
6292             If rect.Left <= spos.X AndAlso spos.X <= rect.Right AndAlso _
6293                rect.Top <= spos.Y AndAlso spos.Y <= rect.Bottom Then
6294                 tn = ListTab.TabPages(i).Text
6295                 If spos.X <= (rect.Left + rect.Right) / 2 Then
6296                     bef = True
6297                 Else
6298                     bef = False
6299                 End If
6300                 Exit For
6301             End If
6302         Next
6303
6304         'タブのないところにドロップ->最後尾へ移動
6305         If String.IsNullOrEmpty(tn) Then
6306             tn = ListTab.TabPages(ListTab.TabPages.Count - 1).Text
6307             bef = False
6308             i = ListTab.TabPages.Count - 1
6309         End If
6310
6311         Dim tp As TabPage = DirectCast(e.Data.GetData(GetType(TabPage)), TabPage)
6312         If tp.Text = tn Then Exit Sub
6313
6314         ReOrderTab(tp.Text, tn, bef)
6315     End Sub
6316
6317     Public Sub ReOrderTab(ByVal targetTabText As String, ByVal baseTabText As String, ByVal isBeforeBaseTab As Boolean)
6318         Dim baseIndex As Integer = 0
6319         For baseIndex = 0 To ListTab.TabPages.Count - 1
6320             If ListTab.TabPages(baseIndex).Text = baseTabText Then Exit For
6321         Next
6322
6323         ListTab.SuspendLayout()
6324
6325         Dim mTp As TabPage = Nothing
6326         For j As Integer = 0 To ListTab.TabPages.Count - 1
6327             If ListTab.TabPages(j).Text = targetTabText Then
6328                 mTp = ListTab.TabPages(j)
6329                 ListTab.TabPages.Remove(mTp)
6330                 If j < baseIndex Then baseIndex -= 1
6331                 Exit For
6332             End If
6333         Next
6334         If isBeforeBaseTab Then
6335             ListTab.TabPages.Insert(baseIndex, mTp)
6336         Else
6337             ListTab.TabPages.Insert(baseIndex + 1, mTp)
6338         End If
6339
6340         ListTab.ResumeLayout()
6341
6342         SaveConfigsTabs()
6343     End Sub
6344
6345     Private Sub MakeReplyOrDirectStatus(Optional ByVal isAuto As Boolean = True, Optional ByVal isReply As Boolean = True, Optional ByVal isAll As Boolean = False)
6346         'isAuto:True=先頭に挿入、False=カーソル位置に挿入
6347         'isReply:True=@,False=DM
6348         If Not StatusText.Enabled Then Exit Sub
6349         If _curList Is Nothing Then Exit Sub
6350         If _curTab Is Nothing Then Exit Sub
6351         If Not Me.ExistCurrentPost Then Exit Sub
6352
6353         ' 複数あてリプライはReplyではなく通常ポスト
6354         '↑仕様変更で全部リプライ扱いでOK(先頭ドット付加しない)
6355         '090403暫定でドットを付加しないようにだけ修正。単独と複数の処理は統合できると思われる。
6356         '090513 all @ replies 廃止の仕様変更によりドット付加に戻し(syo68k)
6357
6358         If _curList.SelectedIndices.Count > 0 Then
6359             ' アイテムが1件以上選択されている
6360             If _curList.SelectedIndices.Count = 1 AndAlso Not isAll AndAlso Me.ExistCurrentPost Then
6361                 ' 単独ユーザー宛リプライまたはDM
6362                 If (_statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.DirectMessage AndAlso isAuto) OrElse (Not isAuto AndAlso Not isReply) Then
6363                     ' ダイレクトメッセージ
6364                     StatusText.Text = "D " + _curPost.ScreenName + " " + StatusText.Text
6365                     StatusText.SelectionStart = StatusText.Text.Length
6366                     StatusText.Focus()
6367                     _reply_to_id = 0
6368                     _reply_to_name = ""
6369                     Exit Sub
6370                 End If
6371                 If String.IsNullOrEmpty(StatusText.Text) Then
6372                     '空の場合
6373
6374                     ' ステータステキストが入力されていない場合先頭に@ユーザー名を追加する
6375                     StatusText.Text = "@" + _curPost.ScreenName + " "
6376                     If _curPost.RetweetedId > 0 Then
6377                         _reply_to_id = _curPost.RetweetedId
6378                     Else
6379                         _reply_to_id = _curPost.StatusId
6380                     End If
6381                     _reply_to_name = _curPost.ScreenName
6382                 Else
6383                     '何か入力済の場合
6384
6385                     If isAuto Then
6386                         '1件選んでEnter or DoubleClick
6387                         If StatusText.Text.Contains("@" + _curPost.ScreenName + " ") Then
6388                             If _reply_to_id > 0 AndAlso _reply_to_name = _curPost.ScreenName Then
6389                                 '返信先書き換え
6390                                 If _curPost.RetweetedId > 0 Then
6391                                     _reply_to_id = _curPost.RetweetedId
6392                                 Else
6393                                     _reply_to_id = _curPost.StatusId
6394                                 End If
6395                                 _reply_to_name = _curPost.ScreenName
6396                             End If
6397                             Exit Sub
6398                         End If
6399                         If Not StatusText.Text.StartsWith("@") Then
6400                             '文頭@以外
6401                             If StatusText.Text.StartsWith(". ") Then
6402                                 ' 複数リプライ
6403                                 StatusText.Text = StatusText.Text.Insert(2, "@" + _curPost.ScreenName + " ")
6404                                 _reply_to_id = 0
6405                                 _reply_to_name = ""
6406                             Else
6407                                 ' 単独リプライ
6408                                 StatusText.Text = "@" + _curPost.ScreenName + " " + StatusText.Text
6409                                 If _curPost.RetweetedId > 0 Then
6410                                     _reply_to_id = _curPost.RetweetedId
6411                                 Else
6412                                     _reply_to_id = _curPost.StatusId
6413                                 End If
6414                                 _reply_to_name = _curPost.ScreenName
6415                             End If
6416                         Else
6417                             '文頭@
6418                             ' 複数リプライ
6419                             StatusText.Text = ". @" + _curPost.ScreenName + " " + StatusText.Text
6420                             'StatusText.Text = "@" + _curPost.ScreenName + " " + StatusText.Text
6421                             _reply_to_id = 0
6422                             _reply_to_name = ""
6423                         End If
6424                     Else
6425                         '1件選んでCtrl-Rの場合(返信先操作せず)
6426                         Dim sidx As Integer = StatusText.SelectionStart
6427                         Dim id As String = "@" + _curPost.ScreenName + " "
6428                         If sidx > 0 Then
6429                             If StatusText.Text.Substring(sidx - 1, 1) <> " " Then
6430                                 id = " " + id
6431                             End If
6432                         End If
6433                         StatusText.Text = StatusText.Text.Insert(sidx, id)
6434                         sidx += id.Length
6435                         'If StatusText.Text.StartsWith("@") Then
6436                         '    '複数リプライ
6437                         '    StatusText.Text = ". " + StatusText.Text.Insert(sidx, " @" + _curPost.ScreenName + " ")
6438                         '    sidx += 5 + _curPost.ScreenName.Length
6439                         'Else
6440                         '    ' 複数リプライ
6441                         '    StatusText.Text = StatusText.Text.Insert(sidx, " @" + _curPost.ScreenName + " ")
6442                         '    sidx += 3 + _curPost.ScreenName.Length
6443                         'End If
6444                         StatusText.SelectionStart = sidx
6445                         StatusText.Focus()
6446                         '_reply_to_id = 0
6447                         '_reply_to_name = Nothing
6448                         Exit Sub
6449                     End If
6450                 End If
6451             Else
6452                 ' 複数リプライ
6453                 If Not isAuto AndAlso Not isReply Then Exit Sub
6454
6455                 'C-S-rか、複数の宛先を選択中にEnter/DoubleClick/C-r/C-S-r
6456
6457                 If isAuto Then
6458                     'Enter or DoubleClick
6459
6460                     Dim sTxt As String = StatusText.Text
6461                     If Not sTxt.StartsWith(". ") Then
6462                         sTxt = ". " + sTxt
6463                         _reply_to_id = 0
6464                         _reply_to_name = ""
6465                     End If
6466                     For cnt As Integer = 0 To _curList.SelectedIndices.Count - 1
6467                         Dim post As PostClass = _statuses.Item(_curTab.Text, _curList.SelectedIndices(cnt))
6468                         If Not sTxt.Contains("@" + post.ScreenName + " ") Then
6469                             sTxt = sTxt.Insert(2, "@" + post.ScreenName + " ")
6470                             'sTxt = "@" + post.ScreenName + " " + sTxt
6471                         End If
6472                     Next
6473                     StatusText.Text = sTxt
6474                 Else
6475                     'C-S-r or C-r
6476                     If _curList.SelectedIndices.Count > 1 Then
6477                         '複数ポスト選択
6478
6479                         Dim ids As String = ""
6480                         Dim sidx As Integer = StatusText.SelectionStart
6481                         For cnt As Integer = 0 To _curList.SelectedIndices.Count - 1
6482                             Dim post As PostClass = _statuses.Item(_curTab.Text, _curList.SelectedIndices(cnt))
6483                             If Not ids.Contains("@" + post.ScreenName + " ") AndAlso _
6484                                Not post.ScreenName.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase) Then
6485                                 ids += "@" + post.ScreenName + " "
6486                             End If
6487                             If isAll Then
6488                                 For Each nm As String In post.ReplyToList
6489                                     If Not ids.Contains("@" + nm + " ") AndAlso _
6490                                        Not nm.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase) Then
6491                                         Dim m As Match = Regex.Match(post.TextFromApi, "[@@](?<id>" + nm + ")([^a-zA-Z0-9]|$)", RegexOptions.IgnoreCase)
6492                                         If m.Success Then
6493                                             ids += "@" + m.Result("${id}") + " "
6494                                         Else
6495                                             ids += "@" + nm + " "
6496                                         End If
6497                                     End If
6498                                 Next
6499                             End If
6500                         Next
6501                         If ids.Length = 0 Then Exit Sub
6502                         If Not StatusText.Text.StartsWith(". ") Then
6503                             StatusText.Text = ". " + StatusText.Text
6504                             sidx += 2
6505                             _reply_to_id = 0
6506                             _reply_to_name = ""
6507                         End If
6508                         If sidx > 0 Then
6509                             If StatusText.Text.Substring(sidx - 1, 1) <> " " Then
6510                                 ids = " " + ids
6511                             End If
6512                         End If
6513                         StatusText.Text = StatusText.Text.Insert(sidx, ids)
6514                         sidx += ids.Length
6515                         'If StatusText.Text.StartsWith("@") Then
6516                         '    StatusText.Text = ". " + StatusText.Text.Insert(sidx, ids)
6517                         '    sidx += 2 + ids.Length
6518                         'Else
6519                         '    StatusText.Text = StatusText.Text.Insert(sidx, ids)
6520                         '    sidx += 1 + ids.Length
6521                         'End If
6522                         StatusText.SelectionStart = sidx
6523                         StatusText.Focus()
6524                         Exit Sub
6525                     Else
6526                         '1件のみ選択のC-S-r(返信元付加する可能性あり)
6527
6528                         Dim ids As String = ""
6529                         Dim sidx As Integer = StatusText.SelectionStart
6530                         Dim post As PostClass = _curPost
6531                         If Not ids.Contains("@" + post.ScreenName + " ") AndAlso _
6532                            Not post.ScreenName.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase) Then
6533                             ids += "@" + post.ScreenName + " "
6534                         End If
6535                         For Each nm As String In post.ReplyToList
6536                             If Not ids.Contains("@" + nm + " ") AndAlso _
6537                                Not nm.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase) Then
6538                                 Dim m As Match = Regex.Match(post.TextFromApi, "[@@](?<id>" + nm + ")([^a-zA-Z0-9]|$)", RegexOptions.IgnoreCase)
6539                                 If m.Success Then
6540                                     ids += "@" + m.Result("${id}") + " "
6541                                 Else
6542                                     ids += "@" + nm + " "
6543                                 End If
6544                             End If
6545                         Next
6546                         If Not String.IsNullOrEmpty(post.RetweetedBy) Then
6547                             If Not ids.Contains("@" + post.RetweetedBy + " ") AndAlso _
6548                                Not post.RetweetedBy.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase) Then
6549                                 ids += "@" + post.RetweetedBy + " "
6550                             End If
6551                         End If
6552                         If ids.Length = 0 Then Exit Sub
6553                         If String.IsNullOrEmpty(StatusText.Text) Then
6554                             '未入力の場合のみ返信先付加
6555                             StatusText.Text = ids
6556                             StatusText.SelectionStart = ids.Length
6557                             StatusText.Focus()
6558                             If post.RetweetedId > 0 Then
6559                                 _reply_to_id = post.RetweetedId
6560                             Else
6561                                 _reply_to_id = post.StatusId
6562                             End If
6563                             _reply_to_name = post.ScreenName
6564                             Exit Sub
6565                         End If
6566
6567                         If sidx > 0 Then
6568                             If StatusText.Text.Substring(sidx - 1, 1) <> " " Then
6569                                 ids = " " + ids
6570                             End If
6571                         End If
6572                         StatusText.Text = StatusText.Text.Insert(sidx, ids)
6573                         sidx += ids.Length
6574                         StatusText.SelectionStart = sidx
6575                         StatusText.Focus()
6576                         Exit Sub
6577                     End If
6578                 End If
6579             End If
6580             StatusText.SelectionStart = StatusText.Text.Length
6581             StatusText.Focus()
6582         End If
6583     End Sub
6584
6585     Private Sub ListTab_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseUp
6586         _tabDrag = False
6587     End Sub
6588
6589     Private Sub RefreshTasktrayIcon(ByVal forceRefresh As Boolean)
6590         If _colorize Then Colorize()
6591         If Not TimerRefreshIcon.Enabled Then Exit Sub
6592         Static iconCnt As Integer = 0
6593         Static blinkCnt As Integer = 0
6594         Static blink As Boolean = False
6595         Static idle As Boolean = False
6596         'Static usCheckCnt As Integer = 0
6597
6598         'Static iconDlListTopItem As ListViewItem = Nothing
6599
6600         If forceRefresh Then idle = False
6601
6602         'If DirectCast(ListTab.SelectedTab.Tag, ListView).TopItem Is iconDlListTopItem Then
6603         '    DirectCast(Me.TIconDic, ImageDictionary).PauseGetImage = False
6604         'Else
6605         '    DirectCast(Me.TIconDic, ImageDictionary).PauseGetImage = True
6606         'End If
6607         'iconDlListTopItem = DirectCast(ListTab.SelectedTab.Tag, ListView).TopItem
6608
6609         iconCnt += 1
6610         blinkCnt += 1
6611         'usCheckCnt += 1
6612
6613         'If usCheckCnt > 300 Then    '1min
6614         '    usCheckCnt = 0
6615         '    If Not Me.IsReceivedUserStream Then
6616         '        TraceOut("ReconnectUserStream")
6617         '        tw.ReconnectUserStream()
6618         '    End If
6619         'End If
6620
6621         Dim busy As Boolean = False
6622         For Each bw As BackgroundWorker In Me._bw
6623             If bw IsNot Nothing AndAlso bw.IsBusy Then
6624                 busy = True
6625                 Exit For
6626             End If
6627         Next
6628
6629         If iconCnt > 3 Then
6630             iconCnt = 0
6631         End If
6632         If blinkCnt > 10 Then
6633             blinkCnt = 0
6634             '未保存の変更を保存
6635             SaveConfigsAll(True)
6636         End If
6637
6638         If busy Then
6639             NotifyIcon1.Icon = NIconRefresh(iconCnt)
6640             idle = False
6641             _myStatusError = False
6642             Exit Sub
6643         End If
6644
6645         Dim tb As TabClass = _statuses.GetTabByType(TabUsageType.Mentions)
6646         If SettingDialog.ReplyIconState <> REPLY_ICONSTATE.None AndAlso tb IsNot Nothing AndAlso tb.UnreadCount > 0 Then
6647             If blinkCnt > 0 Then Exit Sub
6648             blink = Not blink
6649             If blink OrElse SettingDialog.ReplyIconState = REPLY_ICONSTATE.StaticIcon Then
6650                 NotifyIcon1.Icon = ReplyIcon
6651             Else
6652                 NotifyIcon1.Icon = ReplyIconBlink
6653             End If
6654             idle = False
6655             Exit Sub
6656         End If
6657
6658         If idle Then Exit Sub
6659         idle = True
6660         '優先度:エラー→オフライン→アイドル
6661         'エラーは更新アイコンでクリアされる
6662         If _myStatusError Then
6663             NotifyIcon1.Icon = NIconAtRed
6664             Exit Sub
6665         End If
6666         If _myStatusOnline Then
6667             NotifyIcon1.Icon = NIconAt
6668         Else
6669             NotifyIcon1.Icon = NIconAtSmoke
6670         End If
6671     End Sub
6672
6673     Private Sub TimerRefreshIcon_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerRefreshIcon.Tick
6674         '200ms
6675         Me.RefreshTasktrayIcon(False)
6676     End Sub
6677
6678     Private Sub ContextMenuTabProperty_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuTabProperty.Opening
6679         '右クリックの場合はタブ名が設定済。アプリケーションキーの場合は現在のタブを対象とする
6680         If String.IsNullOrEmpty(_rclickTabName) OrElse sender IsNot ContextMenuTabProperty Then
6681             If ListTab IsNot Nothing AndAlso ListTab.SelectedTab IsNot Nothing Then
6682                 _rclickTabName = ListTab.SelectedTab.Text
6683             Else
6684                 Exit Sub
6685             End If
6686         End If
6687
6688         If _statuses Is Nothing Then Exit Sub
6689         If _statuses.Tabs Is Nothing Then Exit Sub
6690
6691         Dim tb As TabClass = _statuses.Tabs(_rclickTabName)
6692         If tb Is Nothing Then Exit Sub
6693
6694         NotifyDispMenuItem.Checked = tb.Notify
6695         Me.NotifyTbMenuItem.Checked = tb.Notify
6696
6697         soundfileListup = True
6698         SoundFileComboBox.Items.Clear()
6699         Me.SoundFileTbComboBox.Items.Clear()
6700         SoundFileComboBox.Items.Add("")
6701         Me.SoundFileTbComboBox.Items.Add("")
6702         Dim oDir As IO.DirectoryInfo = New IO.DirectoryInfo(My.Application.Info.DirectoryPath + IO.Path.DirectorySeparatorChar)
6703         If IO.Directory.Exists(IO.Path.Combine(My.Application.Info.DirectoryPath, "Sounds")) Then
6704             oDir = oDir.GetDirectories("Sounds")(0)
6705         End If
6706         For Each oFile As IO.FileInfo In oDir.GetFiles("*.wav")
6707             SoundFileComboBox.Items.Add(oFile.Name)
6708             Me.SoundFileTbComboBox.Items.Add(oFile.Name)
6709         Next
6710         Dim idx As Integer = SoundFileComboBox.Items.IndexOf(tb.SoundFile)
6711         If idx = -1 Then idx = 0
6712         SoundFileComboBox.SelectedIndex = idx
6713         Me.SoundFileTbComboBox.SelectedIndex = idx
6714         soundfileListup = False
6715         UreadManageMenuItem.Checked = tb.UnreadManage
6716         Me.UnreadMngTbMenuItem.Checked = tb.UnreadManage
6717
6718         TabMenuControl(_rclickTabName)
6719     End Sub
6720
6721     Private Sub TabMenuControl(ByVal tabName As String)
6722         If _statuses.Tabs(tabName).TabType <> TabUsageType.Mentions AndAlso _statuses.IsDefaultTab(tabName) Then
6723             FilterEditMenuItem.Enabled = True
6724             Me.EditRuleTbMenuItem.Enabled = True
6725             DeleteTabMenuItem.Enabled = False
6726             Me.DeleteTbMenuItem.Enabled = False
6727         ElseIf _statuses.Tabs(tabName).TabType = TabUsageType.Mentions Then
6728             FilterEditMenuItem.Enabled = True
6729             Me.EditRuleTbMenuItem.Enabled = True
6730             DeleteTabMenuItem.Enabled = False
6731             Me.DeleteTbMenuItem.Enabled = False
6732         Else
6733             FilterEditMenuItem.Enabled = True
6734             Me.EditRuleTbMenuItem.Enabled = True
6735             DeleteTabMenuItem.Enabled = True
6736             Me.DeleteTbMenuItem.Enabled = True
6737         End If
6738     End Sub
6739
6740     Private Sub UreadManageMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UreadManageMenuItem.Click, UnreadMngTbMenuItem.Click
6741         UreadManageMenuItem.Checked = DirectCast(sender, ToolStripMenuItem).Checked
6742         Me.UnreadMngTbMenuItem.Checked = UreadManageMenuItem.Checked
6743
6744         If String.IsNullOrEmpty(_rclickTabName) Then Exit Sub
6745         ChangeTabUnreadManage(_rclickTabName, UreadManageMenuItem.Checked)
6746
6747         SaveConfigsTabs()
6748     End Sub
6749
6750     Public Sub ChangeTabUnreadManage(ByVal tabName As String, ByVal isManage As Boolean)
6751
6752         Dim idx As Integer
6753         For idx = 0 To ListTab.TabCount
6754             If ListTab.TabPages(idx).Text = tabName Then Exit For
6755         Next
6756
6757         _statuses.SetTabUnreadManage(tabName, isManage)
6758         If SettingDialog.TabIconDisp Then
6759             If _statuses.Tabs(tabName).UnreadCount > 0 Then
6760                 ListTab.TabPages(idx).ImageIndex = 0
6761             Else
6762                 ListTab.TabPages(idx).ImageIndex = -1
6763             End If
6764         End If
6765
6766         If _curTab.Text = tabName Then
6767             _itemCache = Nothing
6768             _postCache = Nothing
6769             _curList.Refresh()
6770         End If
6771
6772         SetMainWindowTitle()
6773         SetStatusLabelUrl()
6774         If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
6775     End Sub
6776
6777     Private Sub NotifyDispMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NotifyDispMenuItem.Click, NotifyTbMenuItem.Click
6778         NotifyDispMenuItem.Checked = DirectCast(sender, ToolStripMenuItem).Checked
6779         Me.NotifyTbMenuItem.Checked = NotifyDispMenuItem.Checked
6780
6781         If String.IsNullOrEmpty(_rclickTabName) Then Exit Sub
6782
6783         _statuses.Tabs(_rclickTabName).Notify = NotifyDispMenuItem.Checked
6784
6785         SaveConfigsTabs()
6786     End Sub
6787
6788     Private Sub SoundFileComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SoundFileComboBox.SelectedIndexChanged, SoundFileTbComboBox.SelectedIndexChanged
6789         If soundfileListup OrElse _rclickTabName = "" Then Exit Sub
6790
6791         _statuses.Tabs(_rclickTabName).SoundFile = DirectCast(DirectCast(sender, ToolStripComboBox).SelectedItem, String)
6792
6793         SaveConfigsTabs()
6794     End Sub
6795
6796     Private Sub DeleteTabMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DeleteTabMenuItem.Click, DeleteTbMenuItem.Click
6797         If String.IsNullOrEmpty(_rclickTabName) OrElse sender Is Me.DeleteTbMenuItem Then _rclickTabName = ListTab.SelectedTab.Text
6798
6799         RemoveSpecifiedTab(_rclickTabName, True)
6800         SaveConfigsTabs()
6801     End Sub
6802
6803     Private Sub FilterEditMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FilterEditMenuItem.Click, EditRuleTbMenuItem.Click
6804
6805         If String.IsNullOrEmpty(_rclickTabName) Then _rclickTabName = _statuses.GetTabByType(TabUsageType.Home).TabName
6806         fltDialog.SetCurrent(_rclickTabName)
6807         fltDialog.ShowDialog()
6808         Me.TopMost = SettingDialog.AlwaysTop
6809
6810         Try
6811             Me.Cursor = Cursors.WaitCursor
6812             _itemCache = Nothing
6813             _postCache = Nothing
6814             _curPost = Nothing
6815             _curItemIndex = -1
6816             _statuses.FilterAll()
6817             For Each tb As TabPage In ListTab.TabPages
6818                 DirectCast(tb.Tag, DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
6819                 If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
6820                     If SettingDialog.TabIconDisp Then
6821                         tb.ImageIndex = 0
6822                     End If
6823                 Else
6824                     If SettingDialog.TabIconDisp Then
6825                         tb.ImageIndex = -1
6826                     End If
6827                 End If
6828             Next
6829             If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
6830         Finally
6831             Me.Cursor = Cursors.Default
6832         End Try
6833         SaveConfigsTabs()
6834     End Sub
6835
6836     Private Sub AddTabMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddTabMenuItem.Click, CreateTbMenuItem.Click
6837         Dim tabName As String = Nothing
6838         Dim tabUsage As TabUsageType
6839         Using inputName As New InputTabName()
6840             inputName.TabName = _statuses.GetUniqueTabName
6841             inputName.IsShowUsage = True
6842             inputName.ShowDialog()
6843             If inputName.DialogResult = Windows.Forms.DialogResult.Cancel Then Exit Sub
6844             tabName = inputName.TabName
6845             tabUsage = inputName.Usage
6846             inputName.Dispose()
6847         End Using
6848         Me.TopMost = SettingDialog.AlwaysTop
6849         If Not String.IsNullOrEmpty(tabName) Then
6850             'List対応
6851             Dim list As ListElement = Nothing
6852             If tabUsage = TabUsageType.Lists Then
6853                 Using listAvail As New ListAvailable
6854                     If listAvail.ShowDialog(Me) = Windows.Forms.DialogResult.Cancel Then Exit Sub
6855                     If listAvail.SelectedList Is Nothing Then Exit Sub
6856                     list = listAvail.SelectedList
6857                 End Using
6858             End If
6859             If Not AddNewTab(tabName, False, tabUsage, list) Then
6860                 Dim tmp As String = String.Format(My.Resources.AddTabMenuItem_ClickText1, tabName)
6861                 MessageBox.Show(tmp, My.Resources.AddTabMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
6862             Else
6863                 '成功
6864                 _statuses.AddTab(tabName, tabUsage, list)
6865                 SaveConfigsTabs()
6866                 If tabUsage = TabUsageType.PublicSearch Then
6867                     ListTab.SelectedIndex = ListTab.TabPages.Count - 1
6868                     ListTabSelect(ListTab.TabPages(ListTab.TabPages.Count - 1))
6869                     ListTab.SelectedTab.Controls("panelSearch").Controls("comboSearch").Focus()
6870                 End If
6871                 If tabUsage = TabUsageType.Lists Then
6872                     ListTab.SelectedIndex = ListTab.TabPages.Count - 1
6873                     ListTabSelect(ListTab.TabPages(ListTab.TabPages.Count - 1))
6874                     GetTimeline(WORKERTYPE.List, 1, 0, tabName)
6875                 End If
6876             End If
6877         End If
6878     End Sub
6879
6880     Private Sub TabMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TabMenuItem.Click, CreateTabRuleOpMenuItem.Click
6881         '選択発言を元にフィルタ追加
6882         For Each idx As Integer In _curList.SelectedIndices
6883             Dim tabName As String = ""
6884             'タブ選択(or追加)
6885             If Not SelectTab(tabName) Then Exit Sub
6886
6887             fltDialog.SetCurrent(tabName)
6888             If _statuses.Item(_curTab.Text, idx).RetweetedId = 0 Then
6889                 fltDialog.AddNewFilter(_statuses.Item(_curTab.Text, idx).ScreenName, _statuses.Item(_curTab.Text, idx).TextFromApi)
6890             Else
6891                 fltDialog.AddNewFilter(_statuses.Item(_curTab.Text, idx).RetweetedBy, _statuses.Item(_curTab.Text, idx).TextFromApi)
6892             End If
6893             fltDialog.ShowDialog()
6894             Me.TopMost = SettingDialog.AlwaysTop
6895         Next
6896
6897         Try
6898             Me.Cursor = Cursors.WaitCursor
6899             _itemCache = Nothing
6900             _postCache = Nothing
6901             _curPost = Nothing
6902             _curItemIndex = -1
6903             _statuses.FilterAll()
6904             For Each tb As TabPage In ListTab.TabPages
6905                 DirectCast(tb.Tag, DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
6906                 If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
6907                     If SettingDialog.TabIconDisp Then
6908                         tb.ImageIndex = 0
6909                     End If
6910                 Else
6911                     If SettingDialog.TabIconDisp Then
6912                         tb.ImageIndex = -1
6913                     End If
6914                 End If
6915             Next
6916             If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
6917         Finally
6918             Me.Cursor = Cursors.Default
6919         End Try
6920         SaveConfigsTabs()
6921         If Me.ListTab.SelectedTab IsNot Nothing AndAlso
6922             DirectCast(Me.ListTab.SelectedTab.Tag, DetailsListView).SelectedIndices.Count > 0 Then
6923             _curPost = _statuses.Item(Me.ListTab.SelectedTab.Text, DirectCast(Me.ListTab.SelectedTab.Tag, DetailsListView).SelectedIndices(0))
6924         End If
6925     End Sub
6926
6927     Protected Overrides Function ProcessDialogKey( _
6928         ByVal keyData As Keys) As Boolean
6929         'TextBox1でEnterを押してもビープ音が鳴らないようにする
6930         If (keyData And Keys.KeyCode) = Keys.Enter Then
6931             If StatusText.Focused Then
6932                 Dim _NewLine As Boolean = False
6933                 Dim _Post As Boolean = False
6934
6935                 If SettingDialog.PostCtrlEnter Then 'Ctrl+Enter投稿時
6936                     If StatusText.Multiline Then
6937                         If (keyData And Keys.Shift) = Keys.Shift AndAlso (keyData And Keys.Control) <> Keys.Control Then _NewLine = True
6938
6939                         If (keyData And Keys.Control) = Keys.Control Then _Post = True
6940                     Else
6941                         If ((keyData And Keys.Control) = Keys.Control) Then _Post = True
6942                     End If
6943
6944                 ElseIf SettingDialog.PostShiftEnter Then 'SHift+Enter投稿時
6945                     If StatusText.Multiline Then
6946                         If (keyData And Keys.Control) = Keys.Control AndAlso (keyData And Keys.Shift) <> Keys.Shift Then _NewLine = True
6947
6948                         If (keyData And Keys.Shift) = Keys.Shift Then _Post = True
6949                     Else
6950                         If ((keyData And Keys.Shift) = Keys.Shift) Then _Post = True
6951                     End If
6952
6953                 Else 'Enter投稿時
6954                     If StatusText.Multiline Then
6955                         If (keyData And Keys.Shift) = Keys.Shift AndAlso (keyData And Keys.Control) <> Keys.Control Then _NewLine = True
6956
6957                         If ((keyData And Keys.Control) <> Keys.Control AndAlso (keyData And Keys.Shift) <> Keys.Shift) OrElse _
6958                             ((keyData And Keys.Control) = Keys.Control AndAlso (keyData And Keys.Shift) = Keys.Shift) Then _Post = True
6959                     Else
6960                         If ((keyData And Keys.Shift) = Keys.Shift) OrElse _
6961                            (((keyData And Keys.Control) <> Keys.Control) AndAlso _
6962                             ((keyData And Keys.Shift) <> Keys.Shift)) Then _Post = True
6963                     End If
6964                 End If
6965
6966                 If _NewLine Then
6967                     Dim pos1 As Integer = StatusText.SelectionStart
6968                     If StatusText.SelectionLength > 0 Then
6969                         StatusText.Text = StatusText.Text.Remove(pos1, StatusText.SelectionLength)  '選択状態文字列削除
6970                     End If
6971                     StatusText.Text = StatusText.Text.Insert(pos1, Environment.NewLine)  '改行挿入
6972                     StatusText.SelectionStart = pos1 + Environment.NewLine.Length    'カーソルを改行の次の文字へ移動
6973                     Return True
6974                 ElseIf _Post Then
6975                     PostButton_Click(Nothing, Nothing)
6976                     Return True
6977                 End If
6978             ElseIf _statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.PublicSearch AndAlso _
6979                     (ListTab.SelectedTab.Controls("panelSearch").Controls("comboSearch").Focused OrElse _
6980                     ListTab.SelectedTab.Controls("panelSearch").Controls("comboLang").Focused) Then
6981                 Me.SearchButton_Click(ListTab.SelectedTab.Controls("panelSearch").Controls("comboSearch"), Nothing)
6982                 Return True
6983             End If
6984         End If
6985
6986         Return MyBase.ProcessDialogKey(keyData)
6987     End Function
6988
6989     Private Sub ReplyAllStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReplyAllStripMenuItem.Click, ReplyAllOpMenuItem.Click
6990         MakeReplyOrDirectStatus(False, True, True)
6991     End Sub
6992
6993     Private Sub IDRuleMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IDRuleMenuItem.Click, CreateIdRuleOpMenuItem.Click
6994         Dim tabName As String = ""
6995
6996         '未選択なら処理終了
6997         If _curList.SelectedIndices.Count = 0 Then Exit Sub
6998
6999         'タブ選択(or追加)
7000         If Not SelectTab(tabName) Then Exit Sub
7001
7002         Dim mv As Boolean = False
7003         Dim mk As Boolean = False
7004         MoveOrCopy(mv, mk)
7005
7006         Dim ids As New List(Of String)
7007         For Each idx As Integer In _curList.SelectedIndices
7008             Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
7009             If Not ids.Contains(post.ScreenName) Then
7010                 Dim fc As New FiltersClass
7011                 ids.Add(post.ScreenName)
7012                 If post.RetweetedId = 0 Then
7013                     fc.NameFilter = post.ScreenName
7014                 Else
7015                     fc.NameFilter = post.RetweetedBy
7016                 End If
7017                 fc.SearchBoth = True
7018                 fc.MoveFrom = mv
7019                 fc.SetMark = mk
7020                 fc.UseRegex = False
7021                 fc.SearchUrl = False
7022                 _statuses.Tabs(tabName).AddFilter(fc)
7023             End If
7024         Next
7025         If ids.Count <> 0 Then
7026             Dim atids As New List(Of String)
7027             For Each id As String In ids
7028                 atids.Add("@" + id)
7029             Next
7030             Dim cnt As Integer = AtIdSupl.ItemCount
7031             AtIdSupl.AddRangeItem(atids.ToArray)
7032             If AtIdSupl.ItemCount <> cnt Then _modifySettingAtId = True
7033         End If
7034
7035         Try
7036             Me.Cursor = Cursors.WaitCursor
7037             _itemCache = Nothing
7038             _postCache = Nothing
7039             _curPost = Nothing
7040             _curItemIndex = -1
7041             _statuses.FilterAll()
7042             For Each tb As TabPage In ListTab.TabPages
7043                 DirectCast(tb.Tag, DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
7044                 If _statuses.ContainsTab(tb.Text) Then
7045                     If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
7046                         If SettingDialog.TabIconDisp Then
7047                             tb.ImageIndex = 0
7048                         End If
7049                     Else
7050                         If SettingDialog.TabIconDisp Then
7051                             tb.ImageIndex = -1
7052                         End If
7053                     End If
7054                 End If
7055             Next
7056             If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
7057         Finally
7058             Me.Cursor = Cursors.Default
7059         End Try
7060         SaveConfigsTabs()
7061     End Sub
7062
7063     Private Function SelectTab(ByRef tabName As String) As Boolean
7064         Do
7065             '振り分け先タブ選択
7066             If TabDialog.ShowDialog = Windows.Forms.DialogResult.Cancel Then
7067                 Me.TopMost = SettingDialog.AlwaysTop
7068                 Return False
7069             End If
7070             Me.TopMost = SettingDialog.AlwaysTop
7071             tabName = TabDialog.SelectedTabName
7072
7073             ListTab.SelectedTab.Focus()
7074             '新規タブを選択→タブ作成
7075             If tabName = My.Resources.IDRuleMenuItem_ClickText1 Then
7076                 Using inputName As New InputTabName()
7077                     inputName.TabName = _statuses.GetUniqueTabName
7078                     inputName.ShowDialog()
7079                     If inputName.DialogResult = Windows.Forms.DialogResult.Cancel Then Return False
7080                     tabName = inputName.TabName
7081                     inputName.Dispose()
7082                 End Using
7083                 Me.TopMost = SettingDialog.AlwaysTop
7084                 If Not String.IsNullOrEmpty(tabName) Then
7085                     If Not AddNewTab(tabName, False, TabUsageType.UserDefined) Then
7086                         Dim tmp As String = String.Format(My.Resources.IDRuleMenuItem_ClickText2, tabName)
7087                         MessageBox.Show(tmp, My.Resources.IDRuleMenuItem_ClickText3, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
7088                         'もう一度タブ名入力
7089                     Else
7090                         _statuses.AddTab(tabName, TabUsageType.UserDefined, Nothing)
7091                         Return True
7092                     End If
7093                 End If
7094             Else
7095                 '既存タブを選択
7096                 Return True
7097             End If
7098         Loop While True
7099
7100     End Function
7101
7102     Private Sub MoveOrCopy(ByRef move As Boolean, ByRef mark As Boolean)
7103         With Block
7104             '移動するか?
7105             Dim _tmp As String = String.Format(My.Resources.IDRuleMenuItem_ClickText4, Environment.NewLine)
7106             If MessageBox.Show(_tmp, My.Resources.IDRuleMenuItem_ClickText5, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
7107                 move = False
7108             Else
7109                 move = True
7110             End If
7111         End With
7112         If Not move Then
7113             'マークするか?
7114             Dim _tmp As String = String.Format(My.Resources.IDRuleMenuItem_ClickText6, vbCrLf)
7115             If MessageBox.Show(_tmp, My.Resources.IDRuleMenuItem_ClickText7, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
7116                 mark = True
7117             Else
7118                 mark = False
7119             End If
7120         End If
7121     End Sub
7122     Private Sub CopySTOTMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CopySTOTMenuItem.Click
7123         Me.CopyStot()
7124     End Sub
7125
7126     Private Sub CopyURLMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CopyURLMenuItem.Click
7127         Me.CopyIdUri()
7128     End Sub
7129
7130     Private Sub SelectAllMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectAllMenuItem.Click, SelAllOpMenuItem.Click
7131         If StatusText.Focused Then
7132             ' 発言欄でのCtrl+A
7133             StatusText.SelectAll()
7134         Else
7135             ' ListView上でのCtrl+A
7136             For i As Integer = 0 To _curList.VirtualListSize - 1
7137                 _curList.SelectedIndices.Add(i)
7138             Next
7139         End If
7140     End Sub
7141
7142     Private Sub MoveMiddle()
7143         Dim _item As ListViewItem
7144         Dim idx1 As Integer
7145         Dim idx2 As Integer
7146
7147         If _curList.SelectedIndices.Count = 0 Then Exit Sub
7148
7149         Dim idx As Integer = _curList.SelectedIndices(0)
7150
7151         _item = _curList.GetItemAt(0, 25)
7152         If _item Is Nothing Then
7153             idx1 = 0
7154         Else
7155             idx1 = _item.Index
7156         End If
7157         _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1)
7158         If _item Is Nothing Then
7159             idx2 = _curList.VirtualListSize - 1
7160         Else
7161             idx2 = _item.Index
7162         End If
7163
7164         idx -= Math.Abs(idx1 - idx2) \ 2
7165         If idx < 0 Then idx = 0
7166
7167         _curList.EnsureVisible(_curList.VirtualListSize - 1)
7168         _curList.EnsureVisible(idx)
7169     End Sub
7170
7171     Private Sub OpenURLMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenURLMenuItem.Click, OpenUrlOpMenuItem.Click
7172         If PostBrowser.Document.Links.Count > 0 Then
7173             UrlDialog.ClearUrl()
7174
7175             Dim openUrlStr As String = ""
7176
7177             If PostBrowser.Document.Links.Count = 1 Then
7178                 Dim urlStr As String = ""
7179                 Try
7180                     urlStr = IDNDecode(PostBrowser.Document.Links(0).GetAttribute("href"))
7181                 Catch ex As ArgumentException
7182                     '変なHTML?
7183                     Exit Sub
7184                 End Try
7185                 If String.IsNullOrEmpty(urlStr) Then Exit Sub
7186                 openUrlStr = urlEncodeMultibyteChar(urlStr)
7187             Else
7188                 For Each linkElm As HtmlElement In PostBrowser.Document.Links
7189                     Dim urlStr As String = ""
7190                     Dim linkText As String = ""
7191                     Try
7192                         urlStr = IDNDecode(linkElm.GetAttribute("href"))
7193                         linkText = linkElm.InnerText
7194                         If Not linkText.StartsWith("http") AndAlso Not linkText.StartsWith("#") Then
7195                             linkText = "@" + linkText
7196                         End If
7197                     Catch ex As ArgumentException
7198                         '変なHTML?
7199                         Exit Sub
7200                     End Try
7201                     If String.IsNullOrEmpty(urlStr) Then Continue For
7202                     UrlDialog.AddUrl(New OpenUrlItem(linkText, urlEncodeMultibyteChar(urlStr)))
7203                 Next
7204                 Try
7205                     If UrlDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
7206                         openUrlStr = UrlDialog.SelectedUrl
7207                     End If
7208                 Catch ex As Exception
7209                     Exit Sub
7210                 End Try
7211                 Me.TopMost = SettingDialog.AlwaysTop
7212             End If
7213             If String.IsNullOrEmpty(openUrlStr) Then Exit Sub
7214
7215             If openUrlStr.StartsWith("http://twitter.com/search?q=%23") OrElse _
7216                openUrlStr.StartsWith("https://twitter.com/search?q=%23") Then
7217                 'ハッシュタグの場合は、タブで開く
7218                 Dim urlStr As String = HttpUtility.UrlDecode(openUrlStr)
7219                 Dim hash As String = urlStr.Substring(urlStr.IndexOf("#"))
7220                 HashSupl.AddItem(hash)
7221                 HashMgr.AddHashToHistory(hash.Trim, False)
7222                 AddNewTabForSearch(hash)
7223                 Exit Sub
7224             Else
7225                 Dim m As Match = Regex.Match(openUrlStr, "^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)$")
7226                 If SettingDialog.OpenUserTimeline AndAlso m.Success AndAlso IsTwitterId(m.Result("${ScreenName}")) Then
7227                     Me.AddNewTabForUserTimeline(m.Result("${ScreenName}"))
7228                 Else
7229                     OpenUriAsync(openUrlStr)
7230                 End If
7231                 Exit Sub
7232             End If
7233
7234             openUrlStr = openUrlStr.Replace("://twitter.com/search?q=#", "://twitter.com/search?q=%23")
7235             OpenUriAsync(openUrlStr)
7236         End If
7237     End Sub
7238
7239     Private Sub ClearTabMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ClearTabMenuItem.Click, ClearTbMenuItem.Click
7240         If String.IsNullOrEmpty(_rclickTabName) Then Exit Sub
7241         ClearTab(_rclickTabName, True)
7242     End Sub
7243
7244     Private Sub ClearTab(ByVal tabName As String, ByVal showWarning As Boolean)
7245         If showWarning Then
7246             Dim tmp As String = String.Format(My.Resources.ClearTabMenuItem_ClickText1, Environment.NewLine)
7247             If MessageBox.Show(tmp, tabName + " " + My.Resources.ClearTabMenuItem_ClickText2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
7248                 Exit Sub
7249             End If
7250         End If
7251
7252         _statuses.ClearTabIds(tabName)
7253         If ListTab.SelectedTab.Text = tabName Then
7254             _anchorPost = Nothing
7255             _anchorFlag = False
7256             _itemCache = Nothing
7257             _postCache = Nothing
7258             _itemCacheIndex = -1
7259             _curItemIndex = -1
7260             _curPost = Nothing
7261         End If
7262         For Each tb As TabPage In ListTab.TabPages
7263             If tb.Text = tabName Then
7264                 tb.ImageIndex = -1
7265                 DirectCast(tb.Tag, DetailsListView).VirtualListSize = 0
7266                 Exit For
7267             End If
7268         Next
7269         If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
7270
7271         SetMainWindowTitle()
7272         SetStatusLabelUrl()
7273     End Sub
7274
7275     Private Sub SetMainWindowTitle()
7276         'メインウインドウタイトルの書き換え
7277         Dim ttl As New StringBuilder(256)
7278         Dim ur As Integer = 0
7279         Dim al As Integer = 0
7280         Static myVer As String = fileVersion
7281         Static followers As Long = 0
7282         If SettingDialog.DispLatestPost <> DispTitleEnum.None AndAlso _
7283            SettingDialog.DispLatestPost <> DispTitleEnum.Post AndAlso _
7284            SettingDialog.DispLatestPost <> DispTitleEnum.Ver AndAlso _
7285            SettingDialog.DispLatestPost <> DispTitleEnum.OwnStatus Then
7286             For Each key As String In _statuses.Tabs.Keys
7287                 ur += _statuses.Tabs(key).UnreadCount
7288                 al += _statuses.Tabs(key).AllCount
7289             Next
7290         End If
7291
7292         If SettingDialog.DispUsername Then ttl.Append(tw.Username).Append(" - ")
7293         ttl.Append("Tween  ")
7294         Select Case SettingDialog.DispLatestPost
7295             Case DispTitleEnum.Ver
7296                 ttl.Append("Ver:").Append(myVer)
7297             Case DispTitleEnum.Post
7298                 If _history IsNot Nothing AndAlso _history.Count > 1 Then
7299                     ttl.Append(_history(_history.Count - 2).status.Replace(vbCrLf, ""))
7300                 End If
7301             Case DispTitleEnum.UnreadRepCount
7302                 ttl.AppendFormat(My.Resources.SetMainWindowTitleText1, _statuses.GetTabByType(TabUsageType.Mentions).UnreadCount + _statuses.GetTabByType(TabUsageType.DirectMessage).UnreadCount)
7303             Case DispTitleEnum.UnreadAllCount
7304                 ttl.AppendFormat(My.Resources.SetMainWindowTitleText2, ur)
7305             Case DispTitleEnum.UnreadAllRepCount
7306                 ttl.AppendFormat(My.Resources.SetMainWindowTitleText3, ur, _statuses.GetTabByType(TabUsageType.Mentions).UnreadCount + _statuses.GetTabByType(TabUsageType.DirectMessage).UnreadCount)
7307             Case DispTitleEnum.UnreadCountAllCount
7308                 ttl.AppendFormat(My.Resources.SetMainWindowTitleText4, ur, al)
7309             Case DispTitleEnum.OwnStatus
7310                 If followers = 0 AndAlso tw.FollowersCount > 0 Then followers = tw.FollowersCount
7311                 ttl.AppendFormat(My.Resources.OwnStatusTitle, tw.StatusesCount, tw.FriendsCount, tw.FollowersCount, tw.FollowersCount - followers)
7312         End Select
7313
7314         Try
7315             Me.Text = ttl.ToString()
7316         Catch ex As AccessViolationException
7317             '原因不明。ポスト内容に依存か?たまーに発生するが再現せず。
7318         End Try
7319     End Sub
7320
7321     Private Function GetStatusLabelText() As String
7322         'ステータス欄にカウント表示
7323         'タブ未読数/タブ発言数 全未読数/総発言数 (未読@+未読DM数)
7324         If _statuses Is Nothing Then Return ""
7325         Dim tbRep As TabClass = _statuses.GetTabByType(TabUsageType.Mentions)
7326         Dim tbDm As TabClass = _statuses.GetTabByType(TabUsageType.DirectMessage)
7327         If tbRep Is Nothing OrElse tbDm Is Nothing Then Return ""
7328         Dim urat As Integer = tbRep.UnreadCount + tbDm.UnreadCount
7329         Dim ur As Integer = 0
7330         Dim al As Integer = 0
7331         Dim tur As Integer = 0
7332         Dim tal As Integer = 0
7333         Dim slbl As StringBuilder = New StringBuilder(256)
7334         Try
7335             For Each key As String In _statuses.Tabs.Keys
7336                 ur += _statuses.Tabs(key).UnreadCount
7337                 al += _statuses.Tabs(key).AllCount
7338                 If key.Equals(_curTab.Text) Then
7339                     tur = _statuses.Tabs(key).UnreadCount
7340                     tal = _statuses.Tabs(key).AllCount
7341                 End If
7342             Next
7343         Catch ex As Exception
7344             Return ""
7345         End Try
7346
7347         UnreadCounter = ur
7348         UnreadAtCounter = urat
7349
7350         slbl.AppendFormat(My.Resources.SetStatusLabelText1, tur, tal, ur, al, urat, _postTimestamps.Count, _favTimestamps.Count, _tlCount)
7351         If SettingDialog.TimelinePeriodInt = 0 Then
7352             slbl.Append(My.Resources.SetStatusLabelText2)
7353         Else
7354             slbl.Append(SettingDialog.TimelinePeriodInt.ToString() + My.Resources.SetStatusLabelText3)
7355         End If
7356         Return slbl.ToString()
7357     End Function
7358
7359     Delegate Sub SetStatusLabelApiDelegate()
7360
7361     Private Sub SetStatusLabelApiHandler(ByVal sender As Object, ByVal e As ApiInformationChangedEventArgs)
7362         If InvokeRequired AndAlso Not IsDisposed Then
7363             Invoke(New SetStatusLabelApiDelegate(AddressOf SetStatusLabelApi))
7364         Else
7365             SetStatusLabelApi()
7366         End If
7367     End Sub
7368
7369     Private Sub SetStatusLabelApi()
7370         Me._apiGauge.RemainCount = TwitterApiInfo.RemainCount
7371         Me._apiGauge.MaxCount = TwitterApiInfo.MaxCount
7372         Me._apiGauge.ResetTime = TwitterApiInfo.ResetTime
7373     End Sub
7374
7375     Private Sub SetStatusLabelUrl()
7376         StatusLabelUrl.Text = GetStatusLabelText()
7377     End Sub
7378
7379     Public Sub SetStatusLabel(ByVal text As String)
7380         StatusLabel.Text = text
7381     End Sub
7382
7383     Private Sub SetNotifyIconText()
7384         ' タスクトレイアイコンのツールチップテキスト書き換え
7385         ' Tween [未読/@]
7386         Static ur As New StringBuilder(64)
7387         ur.Remove(0, ur.Length)
7388         If SettingDialog.DispUsername Then
7389             ur.Append(tw.Username)
7390             ur.Append(" - ")
7391         End If
7392         ur.Append("Tween")
7393 #If DEBUG Then
7394         ur.Append("(Debug Build)")
7395 #End If
7396         If UnreadCounter <> -1 AndAlso UnreadAtCounter <> -1 Then
7397             ur.Append(" [")
7398             ur.Append(UnreadCounter)
7399             ur.Append("/@")
7400             ur.Append(UnreadAtCounter)
7401             ur.Append("]")
7402         End If
7403         NotifyIcon1.Text = ur.ToString()
7404     End Sub
7405
7406     Friend Sub CheckReplyTo(ByVal StatusText As String)
7407         Dim m As MatchCollection
7408         'ハッシュタグの保存
7409         m = Regex.Matches(StatusText, "(^|[^a-zA-Z0-9_/])(#|#)(?<hash>[a-zA-Z0-9_]+)")
7410         Dim hstr As String = ""
7411         For Each hm As Match In m
7412             If Not IsNumeric(hm.Result("${hash}")) Then
7413                 If Not hstr.Contains("#" + hm.Result("${hash}") + " ") Then
7414                     hstr += "#" + hm.Result("${hash}") + " "
7415                     HashSupl.AddItem("#" + hm.Result("${hash}"))
7416                 End If
7417             End If
7418         Next
7419         If Not String.IsNullOrEmpty(HashMgr.UseHash) AndAlso Not hstr.Contains(HashMgr.UseHash + " ") Then
7420             hstr += HashMgr.UseHash
7421         End If
7422         If Not String.IsNullOrEmpty(hstr) Then HashMgr.AddHashToHistory(hstr.Trim, False)
7423
7424         ' 本当にリプライ先指定すべきかどうかの判定
7425         m = Regex.Matches(StatusText, "(^|[ -/:-@[-^`{-~])(?<id>@[a-zA-Z0-9_]+)")
7426
7427         If SettingDialog.UseAtIdSupplement Then
7428             Dim bCnt As Integer = AtIdSupl.ItemCount
7429             For Each mid As Match In m
7430                 AtIdSupl.AddItem(mid.Result("${id}"))
7431             Next
7432             If bCnt <> AtIdSupl.ItemCount Then _modifySettingAtId = True
7433         End If
7434
7435         ' リプライ先ステータスIDの指定がない場合は指定しない
7436         If _reply_to_id = 0 Then Exit Sub
7437
7438         ' リプライ先ユーザー名がない場合も指定しない
7439         If String.IsNullOrEmpty(_reply_to_name) Then
7440             _reply_to_id = 0
7441             Exit Sub
7442         End If
7443
7444         ' 通常Reply
7445         ' 次の条件を満たす場合に in_reply_to_status_id 指定
7446         ' 1. Twitterによりリンクと判定される @idが文中に1つ含まれる (2009/5/28 リンク化される@IDのみカウントするように修正)
7447         ' 2. リプライ先ステータスIDが設定されている(リストをダブルクリックで返信している)
7448         ' 3. 文中に含まれた@idがリプライ先のポスト者のIDと一致する
7449
7450         If m IsNot Nothing Then
7451             If StatusText.StartsWith("@") Then
7452                 If StatusText.StartsWith("@" + _reply_to_name) Then Exit Sub
7453             Else
7454                 For Each mid As Match In m
7455                     If StatusText.Contains("QT " + mid.Result("${id}") + ":") AndAlso mid.Result("${id}") = "@" + _reply_to_name Then Exit Sub
7456                 Next
7457             End If
7458         End If
7459
7460         _reply_to_id = 0
7461         _reply_to_name = ""
7462
7463     End Sub
7464
7465     Private Sub TweenMain_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Resize
7466         If Not _initialLayout AndAlso SettingDialog.MinimizeToTray AndAlso WindowState = FormWindowState.Minimized Then
7467             Me.Visible = False
7468         End If
7469         If _initialLayout AndAlso _cfgLocal IsNot Nothing AndAlso Me.WindowState = FormWindowState.Normal AndAlso Me.Visible Then
7470             Me.ClientSize = _cfgLocal.FormSize
7471             '_mySize = Me.ClientSize                     'サイズ保持(最小化・最大化されたまま終了した場合の対応用)
7472             Me.DesktopLocation = _cfgLocal.FormLocation
7473             '_myLoc = Me.DesktopLocation                        '位置保持(最小化・最大化されたまま終了した場合の対応用)
7474             If _cfgLocal.SplitterDistance > Me.SplitContainer1.Panel1MinSize AndAlso _cfgLocal.SplitterDistance < Me.SplitContainer1.Height - Me.SplitContainer1.Panel2MinSize - Me.SplitContainer1.SplitterWidth Then
7475                 Me.SplitContainer1.SplitterDistance = _cfgLocal.SplitterDistance 'Splitterの位置設定
7476             End If
7477             '発言欄複数行
7478             StatusText.Multiline = _cfgLocal.StatusMultiline
7479             If StatusText.Multiline Then
7480                 Dim dis As Integer = SplitContainer2.Height - _cfgLocal.StatusTextHeight - SplitContainer2.SplitterWidth
7481                 If dis > SplitContainer2.Panel1MinSize AndAlso dis < SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth Then
7482                     SplitContainer2.SplitterDistance = SplitContainer2.Height - _cfgLocal.StatusTextHeight - SplitContainer2.SplitterWidth
7483                 End If
7484                 StatusText.Height = _cfgLocal.StatusTextHeight
7485             Else
7486                 If SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth > 0 Then
7487                     SplitContainer2.SplitterDistance = SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth
7488                 End If
7489             End If
7490             If _cfgLocal.PreviewDistance > Me.SplitContainer3.Panel1MinSize AndAlso _cfgLocal.PreviewDistance < Me.SplitContainer3.Width - Me.SplitContainer3.Panel2MinSize - Me.SplitContainer3.SplitterWidth Then
7491                 Me.SplitContainer3.SplitterDistance = _cfgLocal.PreviewDistance
7492             End If
7493             _initialLayout = False
7494         End If
7495     End Sub
7496
7497     Private Sub PlaySoundMenuItem_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PlaySoundMenuItem.CheckedChanged, PlaySoundFileMenuItem.CheckStateChanged
7498         PlaySoundMenuItem.Checked = DirectCast(sender, ToolStripMenuItem).Checked
7499         Me.PlaySoundFileMenuItem.Checked = PlaySoundMenuItem.Checked
7500         If PlaySoundMenuItem.Checked Then
7501             SettingDialog.PlaySound = True
7502         Else
7503             SettingDialog.PlaySound = False
7504         End If
7505         _modifySettingCommon = True
7506     End Sub
7507
7508     Private Sub SplitContainer1_SplitterMoved(ByVal sender As Object, ByVal e As System.Windows.Forms.SplitterEventArgs) Handles SplitContainer1.SplitterMoved
7509         If Me.WindowState = FormWindowState.Normal AndAlso Not _initialLayout Then
7510             _mySpDis = SplitContainer1.SplitterDistance
7511             If StatusText.Multiline Then _mySpDis2 = StatusText.Height
7512             _modifySettingLocal = True
7513         End If
7514     End Sub
7515
7516     Private Sub doRepliedStatusOpen()
7517         If Me.ExistCurrentPost AndAlso _curPost.InReplyToUser IsNot Nothing AndAlso _curPost.InReplyToStatusId > 0 Then
7518             If My.Computer.Keyboard.ShiftKeyDown Then
7519                 OpenUriAsync("http://twitter.com/" + _curPost.InReplyToUser + "/status/" + _curPost.InReplyToStatusId.ToString())
7520                 Exit Sub
7521             End If
7522             If _statuses.ContainsKey(_curPost.InReplyToStatusId) Then
7523                 Dim repPost As PostClass = _statuses.Item(_curPost.InReplyToStatusId)
7524                 MessageBox.Show(repPost.ScreenName + " / " + repPost.Nickname + "   (" + repPost.CreatedAt.ToString() + ")" + Environment.NewLine + repPost.TextFromApi)
7525             Else
7526                 For Each tb As TabClass In _statuses.GetTabsByType(TabUsageType.Lists Or TabUsageType.PublicSearch)
7527                     If tb Is Nothing OrElse Not tb.Contains(_curPost.InReplyToStatusId) Then Exit For
7528                     Dim repPost As PostClass = _statuses.Item(_curPost.InReplyToStatusId)
7529                     MessageBox.Show(repPost.ScreenName + " / " + repPost.Nickname + "   (" + repPost.CreatedAt.ToString() + ")" + Environment.NewLine + repPost.TextFromApi)
7530                     Exit Sub
7531                 Next
7532                 OpenUriAsync("http://twitter.com/" + _curPost.InReplyToUser + "/status/" + _curPost.InReplyToStatusId.ToString())
7533             End If
7534         End If
7535     End Sub
7536
7537     Private Sub RepliedStatusOpenMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RepliedStatusOpenMenuItem.Click, OpenRepSourceOpMenuItem.Click
7538         doRepliedStatusOpen()
7539     End Sub
7540
7541     Private Sub ContextMenuUserPicture_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuUserPicture.Opening
7542         '発言詳細のアイコン右クリック時のメニュー制御
7543         If _curList.SelectedIndices.Count > 0 AndAlso _curPost IsNot Nothing Then
7544             Dim name As String = _curPost.ImageUrl
7545             If name IsNot Nothing AndAlso name.Length > 0 Then
7546                 Dim idx As Integer = name.LastIndexOf("/"c)
7547                 If idx <> -1 Then
7548                     name = IO.Path.GetFileName(name.Substring(idx))
7549                     If name.Contains("_normal.") Then
7550                         name = name.Replace("_normal", "")
7551                         Me.IconNameToolStripMenuItem.Text = name
7552                         Me.IconNameToolStripMenuItem.Enabled = True
7553                     Else
7554                         Me.IconNameToolStripMenuItem.Enabled = False
7555                         Me.IconNameToolStripMenuItem.Text = My.Resources.ContextMenuStrip3_OpeningText1
7556                     End If
7557                 Else
7558                     Me.IconNameToolStripMenuItem.Enabled = False
7559                     Me.IconNameToolStripMenuItem.Text = My.Resources.ContextMenuStrip3_OpeningText1
7560                 End If
7561                 If Me.TIconDic(_curPost.ImageUrl) IsNot Nothing Then
7562                     Me.SaveIconPictureToolStripMenuItem.Enabled = True
7563                 Else
7564                     Me.SaveIconPictureToolStripMenuItem.Enabled = False
7565                 End If
7566             Else
7567                 Me.IconNameToolStripMenuItem.Enabled = False
7568                 Me.SaveIconPictureToolStripMenuItem.Enabled = False
7569                 Me.IconNameToolStripMenuItem.Text = My.Resources.ContextMenuStrip3_OpeningText1
7570             End If
7571         Else
7572             Me.IconNameToolStripMenuItem.Enabled = False
7573             Me.SaveIconPictureToolStripMenuItem.Enabled = False
7574             Me.IconNameToolStripMenuItem.Text = My.Resources.ContextMenuStrip3_OpeningText2
7575         End If
7576         If NameLabel.Tag IsNot Nothing Then
7577             Dim id As String = DirectCast(NameLabel.Tag, String)
7578             If id = tw.Username Then
7579                 FollowToolStripMenuItem.Enabled = False
7580                 UnFollowToolStripMenuItem.Enabled = False
7581                 ShowFriendShipToolStripMenuItem.Enabled = False
7582                 ShowUserStatusToolStripMenuItem.Enabled = True
7583                 SearchPostsDetailNameToolStripMenuItem.Enabled = True
7584                 SearchAtPostsDetailNameToolStripMenuItem.Enabled = False
7585                 ListManageUserContextToolStripMenuItem3.Enabled = True
7586             Else
7587                 FollowToolStripMenuItem.Enabled = True
7588                 UnFollowToolStripMenuItem.Enabled = True
7589                 ShowFriendShipToolStripMenuItem.Enabled = True
7590                 ShowUserStatusToolStripMenuItem.Enabled = True
7591                 SearchPostsDetailNameToolStripMenuItem.Enabled = True
7592                 SearchAtPostsDetailNameToolStripMenuItem.Enabled = True
7593                 ListManageUserContextToolStripMenuItem3.Enabled = True
7594             End If
7595         Else
7596             FollowToolStripMenuItem.Enabled = False
7597             UnFollowToolStripMenuItem.Enabled = False
7598             ShowFriendShipToolStripMenuItem.Enabled = False
7599             ShowUserStatusToolStripMenuItem.Enabled = False
7600             SearchPostsDetailNameToolStripMenuItem.Enabled = False
7601             SearchAtPostsDetailNameToolStripMenuItem.Enabled = False
7602             ListManageUserContextToolStripMenuItem3.Enabled = False
7603         End If
7604     End Sub
7605
7606     Private Sub IconNameToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IconNameToolStripMenuItem.Click
7607         If _curPost Is Nothing Then Exit Sub
7608         Dim name As String = _curPost.ImageUrl
7609         OpenUriAsync(name.Remove(name.LastIndexOf("_normal"), 7)) ' "_normal".Length
7610     End Sub
7611
7612     Private Sub SaveOriginalSizeIconPictureToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
7613         If _curPost Is Nothing Then Exit Sub
7614         Dim name As String = _curPost.ImageUrl
7615         name = IO.Path.GetFileNameWithoutExtension(name.Substring(name.LastIndexOf("/"c)))
7616
7617         Me.SaveFileDialog1.FileName = name.Substring(0, name.Length - 8) ' "_normal".Length + 1
7618
7619         If Me.SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
7620             ' STUB
7621         End If
7622     End Sub
7623
7624     Private Sub SaveIconPictureToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveIconPictureToolStripMenuItem.Click
7625         If _curPost Is Nothing Then Exit Sub
7626         Dim name As String = _curPost.ImageUrl
7627
7628         Me.SaveFileDialog1.FileName = name.Substring(name.LastIndexOf("/"c) + 1)
7629
7630         If Me.SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
7631             Try
7632                 Using orgBmp As Image = New Bitmap(TIconDic(name))
7633                     Using bmp2 As New Bitmap(orgBmp.Size.Width, orgBmp.Size.Height)
7634                         Using g As Graphics = Graphics.FromImage(bmp2)
7635                             g.InterpolationMode = Drawing2D.InterpolationMode.High
7636                             g.DrawImage(orgBmp, 0, 0, orgBmp.Size.Width, orgBmp.Size.Height)
7637                             g.Dispose()
7638                         End Using
7639                         bmp2.Save(Me.SaveFileDialog1.FileName)
7640                         bmp2.Dispose()
7641                     End Using
7642                     orgBmp.Dispose()
7643                 End Using
7644             Catch ex As Exception
7645                 '処理中にキャッシュアウトする可能性あり
7646             End Try
7647         End If
7648     End Sub
7649
7650     Private Sub SplitContainer2_Panel2_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SplitContainer2.Panel2.Resize
7651         Me.StatusText.Multiline = Me.SplitContainer2.Panel2.Height > Me.SplitContainer2.Panel2MinSize + 2
7652         MultiLineMenuItem.Checked = Me.StatusText.Multiline
7653         _modifySettingLocal = True
7654     End Sub
7655
7656     Private Sub StatusText_MultilineChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusText.MultilineChanged
7657         If Me.StatusText.Multiline Then
7658             Me.StatusText.ScrollBars = ScrollBars.Vertical
7659         Else
7660             Me.StatusText.ScrollBars = ScrollBars.None
7661         End If
7662         _modifySettingLocal = True
7663     End Sub
7664
7665     Private Sub MultiLineMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MultiLineMenuItem.Click
7666         '発言欄複数行
7667         StatusText.Multiline = MultiLineMenuItem.Checked
7668         _cfgLocal.StatusMultiline = MultiLineMenuItem.Checked
7669         If MultiLineMenuItem.Checked Then
7670             If SplitContainer2.Height - _mySpDis2 - SplitContainer2.SplitterWidth < 0 Then
7671                 SplitContainer2.SplitterDistance = 0
7672             Else
7673                 SplitContainer2.SplitterDistance = SplitContainer2.Height - _mySpDis2 - SplitContainer2.SplitterWidth
7674             End If
7675         Else
7676             SplitContainer2.SplitterDistance = SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth
7677         End If
7678         _modifySettingLocal = True
7679     End Sub
7680
7681     Private Function UrlConvert(ByVal Converter_Type As UrlConverter) As Boolean
7682         'Converter_Type=Nicomsの場合は、nicovideoのみ短縮する
7683         '参考資料 RFC3986 Uniform Resource Identifier (URI): Generic Syntax
7684         'Appendix A.  Collected ABNF for URI
7685         'http://www.ietf.org/rfc/rfc3986.txt
7686
7687         Dim result As String = ""
7688         Const url As String = "(?<before>(?:[^\""':!=]|^|\:))" + _
7689                                    "(?<url>(?<protocol>https?://)" + _
7690                                    "(?<domain>(?:[\.-]|[^\p{P}\s])+\.[a-z]{2,}(?::[0-9]+)?)" + _
7691                                    "(?<path>/[a-z0-9!*'();:&=+$/%#\-_.,~@]*[a-z0-9)=#/]?)?" + _
7692                                    "(?<query>\?[a-z0-9!*'();:&=+$/%#\-_.,~@?]*[a-z0-9_&=#/])?)"
7693
7694         Const nico As String = "^https?://[a-z]+\.(nicovideo|niconicommons|nicolive)\.jp/[a-z]+/[a-z0-9]+$"
7695
7696         If StatusText.SelectionLength > 0 Then
7697             Dim tmp As String = StatusText.SelectedText
7698             ' httpから始まらない場合、ExcludeStringで指定された文字列で始まる場合は対象としない
7699             If tmp.StartsWith("http") Then
7700                 ' 文字列が選択されている場合はその文字列について処理
7701
7702                 'nico.ms使用、nicovideoにマッチしたら変換
7703                 If SettingDialog.Nicoms AndAlso Regex.IsMatch(tmp, nico) Then
7704                     result = nicoms.Shorten(tmp)
7705                 ElseIf Converter_Type <> UrlConverter.Nicoms Then
7706                     '短縮URL変換 日本語を含むかもしれないのでURLエンコードする
7707                     result = ShortUrl.Make(Converter_Type, tmp)
7708                     If result.Equals("Can't convert") Then
7709                         StatusLabel.Text = result.Insert(0, Converter_Type.ToString() + ":")
7710                         Return False
7711                     End If
7712                 Else
7713                     Return True
7714                 End If
7715
7716                 If Not String.IsNullOrEmpty(result) Then
7717                     Dim undotmp As New urlUndo
7718
7719                     StatusText.Select(StatusText.Text.IndexOf(tmp, StringComparison.Ordinal), tmp.Length)
7720                     StatusText.SelectedText = result
7721
7722                     'undoバッファにセット
7723                     undotmp.Before = tmp
7724                     undotmp.After = result
7725
7726                     If urlUndoBuffer Is Nothing Then
7727                         urlUndoBuffer = New List(Of urlUndo)
7728                         UrlUndoToolStripMenuItem.Enabled = True
7729                     End If
7730
7731                     urlUndoBuffer.Add(undotmp)
7732                 End If
7733             End If
7734         Else
7735             ' 正規表現にマッチしたURL文字列をtinyurl化
7736             For Each mt As Match In Regex.Matches(StatusText.Text, url, RegexOptions.IgnoreCase)
7737                 If StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal) = -1 Then Continue For
7738                 Dim tmp As String = mt.Result("${url}")
7739                 If tmp.StartsWith("w", StringComparison.OrdinalIgnoreCase) Then tmp = "http://" + tmp
7740                 Dim undotmp As New urlUndo
7741
7742                 '選んだURLを選択(?)
7743                 StatusText.Select(StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length)
7744
7745                 'nico.ms使用、nicovideoにマッチしたら変換
7746                 If SettingDialog.Nicoms AndAlso Regex.IsMatch(tmp, nico) Then
7747                     result = nicoms.Shorten(tmp)
7748                 ElseIf Converter_Type <> UrlConverter.Nicoms Then
7749                     '短縮URL変換 日本語を含むかもしれないのでURLエンコードする
7750                     result = ShortUrl.Make(Converter_Type, tmp)
7751                     If result.Equals("Can't convert") Then
7752                         StatusLabel.Text = result.Insert(0, Converter_Type.ToString() + ":")
7753                         Continue For
7754                     End If
7755                 Else
7756                     Continue For
7757                 End If
7758
7759                 If Not String.IsNullOrEmpty(result) Then
7760                     StatusText.Select(StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length)
7761                     StatusText.SelectedText = result
7762                     'undoバッファにセット
7763                     undotmp.Before = mt.Result("${url}")
7764                     undotmp.After = result
7765
7766                     If urlUndoBuffer Is Nothing Then
7767                         urlUndoBuffer = New List(Of urlUndo)
7768                         UrlUndoToolStripMenuItem.Enabled = True
7769                     End If
7770
7771                     urlUndoBuffer.Add(undotmp)
7772                 End If
7773             Next
7774         End If
7775
7776         Return True
7777
7778     End Function
7779
7780     Private Sub doUrlUndo()
7781         If urlUndoBuffer IsNot Nothing Then
7782             Dim tmp As String = StatusText.Text
7783             For Each data As urlUndo In urlUndoBuffer
7784                 tmp = tmp.Replace(data.After, data.Before)
7785             Next
7786             StatusText.Text = tmp
7787             urlUndoBuffer = Nothing
7788             UrlUndoToolStripMenuItem.Enabled = False
7789         End If
7790     End Sub
7791
7792     Private Sub TinyURLToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TinyURLToolStripMenuItem.Click
7793         UrlConvert(UrlConverter.TinyUrl)
7794     End Sub
7795
7796     Private Sub IsgdToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IsgdToolStripMenuItem.Click
7797         UrlConvert(UrlConverter.Isgd)
7798     End Sub
7799
7800     Private Sub TwurlnlToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TwurlnlToolStripMenuItem.Click
7801         UrlConvert(UrlConverter.Twurl)
7802     End Sub
7803
7804     Private Sub UxnuMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UxnuMenuItem.Click
7805         UrlConvert(UrlConverter.Uxnu)
7806     End Sub
7807
7808     Private Sub UrlConvertAutoToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UrlConvertAutoToolStripMenuItem.Click
7809         If Not UrlConvert(SettingDialog.AutoShortUrlFirst) Then
7810             Dim svc As UrlConverter = SettingDialog.AutoShortUrlFirst
7811             Dim rnd As New Random()
7812             ' 前回使用した短縮URLサービス以外を選択する
7813             Do
7814                 svc = CType(rnd.Next(System.Enum.GetNames(GetType(UrlConverter)).Length), UrlConverter)
7815             Loop Until svc <> SettingDialog.AutoShortUrlFirst AndAlso svc <> UrlConverter.Nicoms AndAlso svc <> UrlConverter.Unu
7816             UrlConvert(svc)
7817         End If
7818     End Sub
7819
7820     Private Sub UrlUndoToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UrlUndoToolStripMenuItem.Click
7821         doUrlUndo()
7822     End Sub
7823
7824     Private Sub NewPostPopMenuItem_CheckStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles NewPostPopMenuItem.CheckStateChanged, NotifyFileMenuItem.CheckStateChanged
7825         Me.NotifyFileMenuItem.Checked = DirectCast(sender, ToolStripMenuItem).Checked
7826         Me.NewPostPopMenuItem.Checked = Me.NotifyFileMenuItem.Checked
7827         _cfgCommon.NewAllPop = NewPostPopMenuItem.Checked
7828         _modifySettingCommon = True
7829     End Sub
7830
7831     Private Sub ListLockMenuItem_CheckStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListLockMenuItem.CheckStateChanged, LockListFileMenuItem.CheckStateChanged
7832         ListLockMenuItem.Checked = DirectCast(sender, ToolStripMenuItem).Checked
7833         Me.LockListFileMenuItem.Checked = ListLockMenuItem.Checked
7834         _cfgCommon.ListLock = ListLockMenuItem.Checked
7835         _modifySettingCommon = True
7836     End Sub
7837
7838     Private Sub MenuStrip1_MenuActivate(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuStrip1.MenuActivate
7839         ' フォーカスがメニューに移る (MenuStrip1.Tag フラグを立てる)
7840         MenuStrip1.Tag = New Object()
7841         MenuStrip1.Select() ' StatusText がフォーカスを持っている場合 Leave が発生
7842     End Sub
7843
7844     Private Sub MenuStrip1_MenuDeactivate(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuStrip1.MenuDeactivate
7845         If Me.Tag IsNot Nothing Then ' 設定された戻り先へ遷移
7846             If Me.Tag Is Me.ListTab.SelectedTab Then
7847                 DirectCast(Me.ListTab.SelectedTab.Tag, Control).Select()
7848             Else
7849                 DirectCast(Me.Tag, Control).Select()
7850             End If
7851         Else ' 戻り先が指定されていない (初期状態) 場合はタブに遷移
7852             If ListTab.SelectedIndex > -1 AndAlso ListTab.SelectedTab.HasChildren Then
7853                 Me.Tag = ListTab.SelectedTab.Tag
7854                 DirectCast(Me.Tag, Control).Select()
7855             End If
7856         End If
7857         ' フォーカスがメニューに遷移したかどうかを表すフラグを降ろす
7858         MenuStrip1.Tag = Nothing
7859     End Sub
7860
7861     Private Sub MyList_ColumnReordered(ByVal sender As System.Object, ByVal e As ColumnReorderedEventArgs)
7862         Dim lst As DetailsListView = DirectCast(sender, DetailsListView)
7863         If _cfgLocal Is Nothing Then Exit Sub
7864
7865         If _iconCol Then
7866             _cfgLocal.Width1 = lst.Columns(0).Width
7867             _cfgLocal.Width3 = lst.Columns(1).Width
7868         Else
7869             Dim darr(lst.Columns.Count - 1) As Integer
7870             For i As Integer = 0 To lst.Columns.Count - 1
7871                 darr(lst.Columns(i).DisplayIndex) = i
7872             Next
7873             MoveArrayItem(darr, e.OldDisplayIndex, e.NewDisplayIndex)
7874
7875             For i As Integer = 0 To lst.Columns.Count - 1
7876                 Select Case darr(i)
7877                     Case 0
7878                         _cfgLocal.DisplayIndex1 = i
7879                     Case 1
7880                         _cfgLocal.DisplayIndex2 = i
7881                     Case 2
7882                         _cfgLocal.DisplayIndex3 = i
7883                     Case 3
7884                         _cfgLocal.DisplayIndex4 = i
7885                     Case 4
7886                         _cfgLocal.DisplayIndex5 = i
7887                     Case 5
7888                         _cfgLocal.DisplayIndex6 = i
7889                     Case 6
7890                         _cfgLocal.DisplayIndex7 = i
7891                     Case 7
7892                         _cfgLocal.DisplayIndex8 = i
7893                 End Select
7894             Next
7895             _cfgLocal.Width1 = lst.Columns(0).Width
7896             _cfgLocal.Width2 = lst.Columns(1).Width
7897             _cfgLocal.Width3 = lst.Columns(2).Width
7898             _cfgLocal.Width4 = lst.Columns(3).Width
7899             _cfgLocal.Width5 = lst.Columns(4).Width
7900             _cfgLocal.Width6 = lst.Columns(5).Width
7901             _cfgLocal.Width7 = lst.Columns(6).Width
7902             _cfgLocal.Width8 = lst.Columns(7).Width
7903         End If
7904         _modifySettingLocal = True
7905         _isColumnChanged = True
7906     End Sub
7907
7908     Private Sub MyList_ColumnWidthChanged(ByVal sender As System.Object, ByVal e As ColumnWidthChangedEventArgs)
7909         Dim lst As DetailsListView = DirectCast(sender, DetailsListView)
7910         If _cfgLocal Is Nothing Then Exit Sub
7911         If _iconCol Then
7912             If _cfgLocal.Width1 <> lst.Columns(0).Width Then
7913                 _cfgLocal.Width1 = lst.Columns(0).Width
7914                 _modifySettingLocal = True
7915                 _isColumnChanged = True
7916             End If
7917             If _cfgLocal.Width3 <> lst.Columns(1).Width Then
7918                 _cfgLocal.Width3 = lst.Columns(1).Width
7919                 _modifySettingLocal = True
7920                 _isColumnChanged = True
7921             End If
7922         Else
7923             If _cfgLocal.Width1 <> lst.Columns(0).Width Then
7924                 _cfgLocal.Width1 = lst.Columns(0).Width
7925                 _modifySettingLocal = True
7926                 _isColumnChanged = True
7927             End If
7928             If _cfgLocal.Width2 <> lst.Columns(1).Width Then
7929                 _cfgLocal.Width2 = lst.Columns(1).Width
7930                 _modifySettingLocal = True
7931                 _isColumnChanged = True
7932             End If
7933             If _cfgLocal.Width3 <> lst.Columns(2).Width Then
7934                 _cfgLocal.Width3 = lst.Columns(2).Width
7935                 _modifySettingLocal = True
7936                 _isColumnChanged = True
7937             End If
7938             If _cfgLocal.Width4 <> lst.Columns(3).Width Then
7939                 _cfgLocal.Width4 = lst.Columns(3).Width
7940                 _modifySettingLocal = True
7941                 _isColumnChanged = True
7942             End If
7943             If _cfgLocal.Width5 <> lst.Columns(4).Width Then
7944                 _cfgLocal.Width5 = lst.Columns(4).Width
7945                 _modifySettingLocal = True
7946                 _isColumnChanged = True
7947             End If
7948             If _cfgLocal.Width6 <> lst.Columns(5).Width Then
7949                 _cfgLocal.Width6 = lst.Columns(5).Width
7950                 _modifySettingLocal = True
7951                 _isColumnChanged = True
7952             End If
7953             If _cfgLocal.Width7 <> lst.Columns(6).Width Then
7954                 _cfgLocal.Width7 = lst.Columns(6).Width
7955                 _modifySettingLocal = True
7956                 _isColumnChanged = True
7957             End If
7958             If _cfgLocal.Width8 <> lst.Columns(7).Width Then
7959                 _cfgLocal.Width8 = lst.Columns(7).Width
7960                 _modifySettingLocal = True
7961                 _isColumnChanged = True
7962             End If
7963         End If
7964         ' 非表示の時にColumnChangedが呼ばれた場合はForm初期化処理中なので保存しない
7965         'If changed Then
7966         '    SaveConfigsLocal()
7967         'End If
7968     End Sub
7969
7970     Public Function WebBrowser_GetSelectionText(ByRef ComponentInstance As WebBrowser) As String
7971         '発言詳細で「選択文字列をコピー」を行う
7972         'WebBrowserコンポーネントのインスタンスを渡す
7973         Dim typ As Type = ComponentInstance.ActiveXInstance.GetType()
7974         Dim _SelObj As Object = typ.InvokeMember("selection", BindingFlags.GetProperty, Nothing, ComponentInstance.Document.DomDocument, Nothing)
7975         Dim _objRange As Object = _SelObj.GetType().InvokeMember("createRange", BindingFlags.InvokeMethod, Nothing, _SelObj, Nothing)
7976         Return DirectCast(_objRange.GetType().InvokeMember("text", BindingFlags.GetProperty, Nothing, _objRange, Nothing), String)
7977     End Function
7978
7979     Private Sub SelectionCopyContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectionCopyContextMenuItem.Click
7980         '発言詳細で「選択文字列をコピー」
7981         Dim _selText As String = WebBrowser_GetSelectionText(PostBrowser)
7982         Try
7983             Clipboard.SetDataObject(_selText, False, 5, 100)
7984         Catch ex As Exception
7985             MessageBox.Show(ex.Message)
7986         End Try
7987     End Sub
7988
7989     Private Sub doSearchToolStrip(ByVal url As String)
7990         '発言詳細で「選択文字列で検索」(選択文字列取得)
7991         Dim _selText As String = WebBrowser_GetSelectionText(PostBrowser)
7992
7993         If _selText IsNot Nothing Then
7994             If url = My.Resources.SearchItem4Url Then
7995                 '公式検索
7996                 AddNewTabForSearch(_selText)
7997                 Exit Sub
7998             End If
7999
8000             Dim tmp As String = String.Format(url, HttpUtility.UrlEncode(_selText))
8001             OpenUriAsync(tmp)
8002         End If
8003     End Sub
8004
8005     Private Sub SelectionAllContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectionAllContextMenuItem.Click
8006         '発言詳細ですべて選択
8007         PostBrowser.Document.ExecCommand("SelectAll", False, Nothing)
8008     End Sub
8009
8010     Private Sub SearchWikipediaContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchWikipediaContextMenuItem.Click
8011         doSearchToolStrip(My.Resources.SearchItem1Url)
8012     End Sub
8013
8014     Private Sub SearchGoogleContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchGoogleContextMenuItem.Click
8015         doSearchToolStrip(My.Resources.SearchItem2Url)
8016     End Sub
8017
8018     Private Sub SearchYatsContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchYatsContextMenuItem.Click
8019         doSearchToolStrip(My.Resources.SearchItem3Url)
8020     End Sub
8021
8022     Private Sub SearchPublicSearchContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchPublicSearchContextMenuItem.Click
8023         doSearchToolStrip(My.Resources.SearchItem4Url)
8024     End Sub
8025
8026     Private Sub UrlCopyContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UrlCopyContextMenuItem.Click
8027         Try
8028             Clipboard.SetDataObject(Me._postBrowserStatusText, False, 5, 100)
8029         Catch ex As Exception
8030             MessageBox.Show(ex.Message)
8031         End Try
8032     End Sub
8033
8034     Private Sub ContextMenuPostBrowser_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuPostBrowser.Opening
8035         ' URLコピーの項目の表示/非表示
8036         If PostBrowser.StatusText.StartsWith("http") Then
8037             Me._postBrowserStatusText = PostBrowser.StatusText
8038             Dim name As String = GetUserId()
8039             UrlCopyContextMenuItem.Enabled = True
8040             If name IsNot Nothing Then
8041                 FollowContextMenuItem.Enabled = True
8042                 RemoveContextMenuItem.Enabled = True
8043                 FriendshipContextMenuItem.Enabled = True
8044                 ShowUserStatusContextMenuItem.Enabled = True
8045                 SearchPostsDetailToolStripMenuItem.Enabled = True
8046                 IdFilterAddMenuItem.Enabled = True
8047                 ListManageUserContextToolStripMenuItem.Enabled = True
8048                 SearchAtPostsDetailToolStripMenuItem.Enabled = True
8049             Else
8050                 FollowContextMenuItem.Enabled = False
8051                 RemoveContextMenuItem.Enabled = False
8052                 FriendshipContextMenuItem.Enabled = False
8053                 ShowUserStatusContextMenuItem.Enabled = False
8054                 SearchPostsDetailToolStripMenuItem.Enabled = False
8055                 IdFilterAddMenuItem.Enabled = False
8056                 ListManageUserContextToolStripMenuItem.Enabled = False
8057                 SearchAtPostsDetailToolStripMenuItem.Enabled = False
8058             End If
8059
8060             If Regex.IsMatch(Me._postBrowserStatusText, "^https?://twitter.com/search\?q=%23") Then
8061                 UseHashtagMenuItem.Enabled = True
8062             Else
8063                 UseHashtagMenuItem.Enabled = False
8064             End If
8065         Else
8066             Me._postBrowserStatusText = ""
8067             UrlCopyContextMenuItem.Enabled = False
8068             FollowContextMenuItem.Enabled = False
8069             RemoveContextMenuItem.Enabled = False
8070             FriendshipContextMenuItem.Enabled = False
8071             ShowUserStatusContextMenuItem.Enabled = False
8072             SearchPostsDetailToolStripMenuItem.Enabled = False
8073             SearchAtPostsDetailToolStripMenuItem.Enabled = False
8074             UseHashtagMenuItem.Enabled = False
8075             IdFilterAddMenuItem.Enabled = False
8076             ListManageUserContextToolStripMenuItem.Enabled = False
8077         End If
8078         ' 文字列選択されていないときは選択文字列関係の項目を非表示に
8079         Dim _selText As String = WebBrowser_GetSelectionText(PostBrowser)
8080         If _selText Is Nothing Then
8081             SelectionSearchContextMenuItem.Enabled = False
8082             SelectionCopyContextMenuItem.Enabled = False
8083             SelectionTranslationToolStripMenuItem.Enabled = False
8084         Else
8085             SelectionSearchContextMenuItem.Enabled = True
8086             SelectionCopyContextMenuItem.Enabled = True
8087             SelectionTranslationToolStripMenuItem.Enabled = True
8088         End If
8089         '発言内に自分以外のユーザーが含まれてればフォロー状態全表示を有効に
8090         Dim ma As MatchCollection = Regex.Matches(Me.PostBrowser.DocumentText, "href=""https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?""")
8091         Dim fAllFlag As Boolean = False
8092         For Each mu As Match In ma
8093             If mu.Result("${ScreenName}").ToLower <> tw.Username.ToLower Then
8094                 fAllFlag = True
8095                 Exit For
8096             End If
8097         Next
8098         Me.FriendshipAllMenuItem.Enabled = fAllFlag
8099
8100         If _curPost Is Nothing Then
8101             TranslationToolStripMenuItem.Enabled = False
8102         Else
8103             TranslationToolStripMenuItem.Enabled = True
8104         End If
8105
8106         e.Cancel = False
8107     End Sub
8108
8109     Private Sub CurrentTabToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CurrentTabToolStripMenuItem.Click
8110         '発言詳細の選択文字列で現在のタブを検索
8111         Dim _selText As String = WebBrowser_GetSelectionText(PostBrowser)
8112
8113         If _selText IsNot Nothing Then
8114             SearchDialog.SWord = _selText
8115             SearchDialog.CheckCaseSensitive = False
8116             SearchDialog.CheckRegex = False
8117
8118             DoTabSearch(SearchDialog.SWord, _
8119                         SearchDialog.CheckCaseSensitive, _
8120                         SearchDialog.CheckRegex, _
8121                         SEARCHTYPE.NextSearch)
8122         End If
8123     End Sub
8124
8125     Private Sub SplitContainer2_SplitterMoved(ByVal sender As Object, ByVal e As System.Windows.Forms.SplitterEventArgs) Handles SplitContainer2.SplitterMoved
8126         If StatusText.Multiline Then _mySpDis2 = StatusText.Height
8127         _modifySettingLocal = True
8128     End Sub
8129
8130     Private Sub TweenMain_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragDrop
8131         If e.Data.GetDataPresent(DataFormats.FileDrop) Then
8132             ImageSelectionPanel.Visible = True
8133             ImageSelectionPanel.Enabled = True
8134             TimelinePanel.Visible = False
8135             TimelinePanel.Enabled = False
8136             ImagefilePathText.Text = CType(e.Data.GetData(DataFormats.FileDrop, False), String())(0)
8137             ImageFromSelectedFile()
8138             Me.Activate()
8139             StatusText.Focus()
8140         ElseIf e.Data.GetDataPresent(DataFormats.StringFormat) Then
8141             Dim data As String = TryCast(e.Data.GetData(DataFormats.StringFormat, True), String)
8142             If data IsNot Nothing Then StatusText.Text += data
8143         End If
8144     End Sub
8145
8146     Private Sub TweenMain_DragOver(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragOver
8147         If e.Data.GetDataPresent(DataFormats.FileDrop) Then
8148             Dim filename As String = CType(e.Data.GetData(DataFormats.FileDrop, False), String())(0)
8149             Dim fl As New FileInfo(filename)
8150             Dim ext As String = fl.Extension
8151
8152             If Not String.IsNullOrEmpty(Me.ImageService) AndAlso Me.pictureService(Me.ImageService).CheckValidFilesize(ext, fl.Length) Then
8153                 e.Effect = DragDropEffects.Copy
8154                 Exit Sub
8155             End If
8156             For Each svc As String In ImageServiceCombo.Items
8157                 If String.IsNullOrEmpty(svc) Then Continue For
8158                 If Me.pictureService(svc).CheckValidFilesize(ext, fl.Length) Then
8159                     ImageServiceCombo.SelectedItem = svc
8160                     e.Effect = DragDropEffects.Copy
8161                     Exit Sub
8162                 End If
8163             Next
8164             e.Effect = DragDropEffects.None
8165         ElseIf e.Data.GetDataPresent(DataFormats.StringFormat) Then
8166             e.Effect = DragDropEffects.Copy
8167         Else
8168             e.Effect = DragDropEffects.None
8169         End If
8170     End Sub
8171
8172     Public Function IsNetworkAvailable() As Boolean
8173         Dim nw As Boolean = True
8174         Try
8175             nw = My.Computer.Network.IsAvailable
8176         Catch ex As Exception
8177             nw = False
8178         End Try
8179         _myStatusOnline = nw
8180         Return nw
8181     End Function
8182
8183     Public Sub OpenUriAsync(ByVal UriString As String)
8184         Dim args As New GetWorkerArg
8185         args.type = WORKERTYPE.OpenUri
8186         args.url = UriString
8187
8188         RunAsync(args)
8189     End Sub
8190
8191     Private Sub ListTabSelect(ByVal _tab As TabPage)
8192         SetListProperty()
8193
8194         _itemCache = Nothing
8195         _itemCacheIndex = -1
8196         _postCache = Nothing
8197
8198         _curTab = _tab
8199         _curList = DirectCast(_tab.Tag, DetailsListView)
8200         If _curList.SelectedIndices.Count > 0 Then
8201             _curItemIndex = _curList.SelectedIndices(0)
8202             _curPost = GetCurTabPost(_curItemIndex)
8203         Else
8204             _curItemIndex = -1
8205             _curPost = Nothing
8206         End If
8207
8208         _anchorPost = Nothing
8209         _anchorFlag = False
8210
8211         If _iconCol Then
8212             DirectCast(_tab.Tag, DetailsListView).Columns.Item(1).Text = ColumnText(2)
8213         Else
8214             For i As Integer = 0 To _curList.Columns.Count - 1
8215                 DirectCast(_tab.Tag, DetailsListView).Columns.Item(i).Text = ColumnText(i)
8216             Next
8217         End If
8218     End Sub
8219
8220     Private Sub ListTab_Selecting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TabControlCancelEventArgs) Handles ListTab.Selecting
8221         ListTabSelect(e.TabPage)
8222     End Sub
8223
8224     Private Sub SelectListItem(ByVal LView As DetailsListView, ByVal Index As Integer)
8225         '単一
8226         Dim bnd As Rectangle
8227         Dim flg As Boolean = False
8228         If LView.FocusedItem IsNot Nothing Then
8229             bnd = LView.FocusedItem.Bounds
8230             flg = True
8231         End If
8232
8233         Do
8234             LView.SelectedIndices.Clear()
8235         Loop While LView.SelectedIndices.Count > 0
8236         LView.Items(Index).Selected = True
8237         'LView.SelectedIndices.Add(Index)
8238         LView.Items(Index).Focused = True
8239
8240         If flg Then LView.Invalidate(bnd)
8241     End Sub
8242
8243     Private Sub SelectListItem(ByVal LView As DetailsListView, ByVal Index() As Integer, ByVal FocusedIndex As Integer)
8244         '複数
8245         Dim bnd As Rectangle
8246         Dim flg As Boolean = False
8247         If LView.FocusedItem IsNot Nothing Then
8248             bnd = LView.FocusedItem.Bounds
8249             flg = True
8250         End If
8251
8252         Dim fIdx As Integer = -1
8253         If Index IsNot Nothing AndAlso Not (Index.Count = 1 AndAlso Index(0) = -1) Then
8254             Do
8255                 LView.SelectedIndices.Clear()
8256             Loop While LView.SelectedIndices.Count > 0
8257             For Each idx As Integer In Index
8258                 If idx > -1 AndAlso LView.VirtualListSize > idx Then
8259                     LView.SelectedIndices.Add(idx)
8260                     If fIdx = -1 Then fIdx = idx
8261                 End If
8262             Next
8263         End If
8264         If FocusedIndex > -1 AndAlso LView.VirtualListSize > FocusedIndex Then
8265             LView.Items(FocusedIndex).Focused = True
8266         ElseIf fIdx > -1 Then
8267             LView.Items(fIdx).Focused = True
8268         End If
8269         If flg Then LView.Invalidate(bnd)
8270     End Sub
8271
8272     Private Sub RunAsync(ByVal args As GetWorkerArg)
8273         Dim bw As BackgroundWorker = Nothing
8274         If args.type <> WORKERTYPE.Follower Then
8275             For i As Integer = 0 To _bw.Length - 1
8276                 If _bw(i) IsNot Nothing AndAlso Not _bw(i).IsBusy Then
8277                     bw = _bw(i)
8278                     Exit For
8279                 End If
8280             Next
8281             If bw Is Nothing Then
8282                 For i As Integer = 0 To _bw.Length - 1
8283                     If _bw(i) Is Nothing Then
8284                         _bw(i) = New BackgroundWorker
8285                         bw = _bw(i)
8286                         bw.WorkerReportsProgress = True
8287                         bw.WorkerSupportsCancellation = True
8288                         AddHandler bw.DoWork, AddressOf GetTimelineWorker_DoWork
8289                         AddHandler bw.ProgressChanged, AddressOf GetTimelineWorker_ProgressChanged
8290                         AddHandler bw.RunWorkerCompleted, AddressOf GetTimelineWorker_RunWorkerCompleted
8291                         Exit For
8292                     End If
8293                 Next
8294             End If
8295         Else
8296             If _bwFollower Is Nothing Then
8297                 _bwFollower = New BackgroundWorker
8298                 bw = _bwFollower
8299                 bw.WorkerReportsProgress = True
8300                 bw.WorkerSupportsCancellation = True
8301                 AddHandler bw.DoWork, AddressOf GetTimelineWorker_DoWork
8302                 AddHandler bw.ProgressChanged, AddressOf GetTimelineWorker_ProgressChanged
8303                 AddHandler bw.RunWorkerCompleted, AddressOf GetTimelineWorker_RunWorkerCompleted
8304             Else
8305                 If _bwFollower.IsBusy = False Then
8306                     bw = _bwFollower
8307                 End If
8308             End If
8309         End If
8310         If bw Is Nothing Then Exit Sub
8311
8312         bw.RunWorkerAsync(args)
8313     End Sub
8314
8315     Private Sub StartUserStream()
8316         AddHandler tw.NewPostFromStream, AddressOf tw_NewPostFromStream
8317         AddHandler tw.UserStreamStarted, AddressOf tw_UserStreamStarted
8318         AddHandler tw.UserStreamStopped, AddressOf tw_UserStreamStopped
8319         AddHandler tw.PostDeleted, AddressOf tw_PostDeleted
8320         AddHandler tw.UserStreamEventReceived, AddressOf tw_UserStreamEventArrived
8321
8322         MenuItemUserStream.Text = "&UserStream ■"
8323         MenuItemUserStream.Enabled = True
8324         StopToolStripMenuItem.Text = "&Start"
8325         StopToolStripMenuItem.Enabled = True
8326         If SettingDialog.UserstreamStartup Then tw.StartUserStream()
8327     End Sub
8328
8329     Private Sub TweenMain_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
8330         Try
8331             PostBrowser.Url = New Uri("about:blank")
8332             PostBrowser.DocumentText = ""       '発言詳細部初期化
8333         Catch ex As Exception
8334
8335         End Try
8336
8337         NotifyIcon1.Visible = True
8338
8339         If IsNetworkAvailable() Then
8340             If SettingDialog.StartupFollowers Then
8341                 GetTimeline(WORKERTYPE.Follower, 0, 0, "")
8342             End If
8343             StartUserStream()
8344             _waitTimeline = True
8345             GetTimeline(WORKERTYPE.Timeline, 1, 1, "")
8346             _waitReply = True
8347             GetTimeline(WORKERTYPE.Reply, 1, 1, "")
8348             _waitDm = True
8349             GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 1, "")
8350             If SettingDialog.GetFav Then
8351                 _waitFav = True
8352                 GetTimeline(WORKERTYPE.Favorites, 1, 1, "")
8353             End If
8354             _waitPubSearch = True
8355             GetTimeline(WORKERTYPE.PublicSearch, 1, 0, "")  'tabname="":全タブ
8356             _waitUserTimeline = True
8357             GetTimeline(WORKERTYPE.UserTimeline, 1, 0, "")  'tabname="":全タブ
8358             _waitLists = True
8359             GetTimeline(WORKERTYPE.List, 1, 0, "")  'tabname="":全タブ
8360             Dim i As Integer = 0
8361             Dim j As Integer = 0
8362             Do While (IsInitialRead()) AndAlso Not _endingFlag
8363                 System.Threading.Thread.Sleep(100)
8364                 My.Application.DoEvents()
8365                 i += 1
8366                 j += 1
8367                 If j > 1200 Then Exit Do ' 120秒間初期処理が終了しなかったら強制的に打ち切る
8368                 If i > 50 Then
8369                     If _endingFlag Then
8370                         Exit Sub
8371                     End If
8372                     i = 0
8373                 End If
8374             Loop
8375
8376             If _endingFlag Then Exit Sub
8377
8378             'バージョンチェック(引数:起動時チェックの場合はTrue・・・チェック結果のメッセージを表示しない)
8379             If SettingDialog.StartupVersion Then
8380                 CheckNewVersion(True)
8381             End If
8382
8383             ' 取得失敗の場合は再試行する
8384             If Not tw.GetFollowersSuccess AndAlso SettingDialog.StartupFollowers Then
8385                 GetTimeline(WORKERTYPE.Follower, 0, 0, "")
8386             End If
8387         End If
8388         _initial = False
8389
8390         TimerTimeline.Enabled = True
8391     End Sub
8392
8393     Private Function IsInitialRead() As Boolean
8394         Return _waitTimeline OrElse _waitReply OrElse _waitDm OrElse _waitFav OrElse _waitPubSearch OrElse _waitUserTimeline OrElse _waitLists
8395     End Function
8396
8397     Private Sub doGetFollowersMenu()
8398         GetTimeline(WORKERTYPE.Follower, 1, 0, "")
8399         DispSelectedPost(True)
8400     End Sub
8401
8402     Private Sub GetFollowersAllToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UpdateFollowersMenuItem1.Click
8403         doGetFollowersMenu()
8404     End Sub
8405
8406     Private Sub doReTweetUnofficial()
8407         'RT @id:内容
8408         If Me.ExistCurrentPost Then
8409             If _curPost.IsDm OrElse _
8410                Not StatusText.Enabled Then Exit Sub
8411
8412             If _curPost.IsProtect Then
8413                 MessageBox.Show("Protected.")
8414                 Exit Sub
8415             End If
8416             Dim rtdata As String = _curPost.Text
8417             rtdata = CreateRetweetUnofficial(rtdata)
8418
8419             StatusText.Text = "RT @" + _curPost.ScreenName + ": " + HttpUtility.HtmlDecode(rtdata)
8420
8421             StatusText.SelectionStart = 0
8422             StatusText.Focus()
8423         End If
8424     End Sub
8425
8426     Private Sub ReTweetStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReTweetStripMenuItem.Click, RtUnOpMenuItem.Click
8427         doReTweetUnofficial()
8428     End Sub
8429
8430     Private Sub doReTweetOfficial(ByVal isConfirm As Boolean)
8431         '公式RT
8432         If Me.ExistCurrentPost Then
8433             If _curPost.IsProtect Then
8434                 MessageBox.Show("Protected.")
8435                 _DoFavRetweetFlags = False
8436                 Exit Sub
8437             End If
8438             If _curList.SelectedIndices.Count > 15 Then
8439                 MessageBox.Show(My.Resources.RetweetLimitText)
8440                 _DoFavRetweetFlags = False
8441                 Exit Sub
8442             ElseIf _curList.SelectedIndices.Count > 1 Then
8443                 Dim QuestionText As String = My.Resources.RetweetQuestion2
8444                 If _DoFavRetweetFlags Then QuestionText = My.Resources.FavoriteRetweetQuestionText1
8445                 Select Case MessageBox.Show(QuestionText, "Retweet", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)
8446                     Case Windows.Forms.DialogResult.Cancel, Windows.Forms.DialogResult.No
8447                         _DoFavRetweetFlags = False
8448                         Exit Sub
8449                 End Select
8450             Else
8451                 If _curPost.IsDm OrElse _curPost.IsMe Then
8452                     _DoFavRetweetFlags = False
8453                     Exit Sub
8454                 End If
8455                 If Not SettingDialog.RetweetNoConfirm Then
8456                     Dim Questiontext As String = My.Resources.RetweetQuestion1
8457                     If _DoFavRetweetFlags Then Questiontext = My.Resources.FavoritesRetweetQuestionText2
8458                     If isConfirm AndAlso MessageBox.Show(Questiontext, "Retweet", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
8459                         _DoFavRetweetFlags = False
8460                         Exit Sub
8461                     End If
8462                 End If
8463             End If
8464             Dim args As New GetWorkerArg
8465             args.ids = New List(Of Long)
8466             args.sIds = New List(Of Long)
8467             args.tName = _curTab.Text
8468             args.type = WORKERTYPE.Retweet
8469             For Each idx As Integer In _curList.SelectedIndices
8470                 Dim post As PostClass = GetCurTabPost(idx)
8471                 If Not post.IsMe AndAlso Not post.IsProtect AndAlso Not post.IsDm Then args.ids.Add(post.StatusId)
8472             Next
8473             RunAsync(args)
8474         End If
8475     End Sub
8476
8477     Private Sub ReTweetOriginalStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReTweetOriginalStripMenuItem.Click, RtOpMenuItem.Click
8478         doReTweetOfficial(True)
8479     End Sub
8480
8481     Private Sub FavoritesRetweetOriginal()
8482         If Not Me.ExistCurrentPost Then Exit Sub
8483         _DoFavRetweetFlags = True
8484         doReTweetOfficial(True)
8485         If _DoFavRetweetFlags Then
8486             _DoFavRetweetFlags = False
8487             FavoriteChange(True, False)
8488         End If
8489     End Sub
8490
8491     Private Sub FavoritesRetweetUnofficial()
8492         If Me.ExistCurrentPost AndAlso Not _curPost.IsDm Then
8493             _DoFavRetweetFlags = True
8494             FavoriteChange(True)
8495             If Not _curPost.IsProtect AndAlso _DoFavRetweetFlags Then
8496                 _DoFavRetweetFlags = False
8497                 doReTweetUnofficial()
8498             End If
8499         End If
8500     End Sub
8501
8502     Private Function CreateRetweetUnofficial(ByVal status As String) As String
8503
8504         ' Twitterにより省略されているURLを含むaタグをキャプチャしてリンク先URLへ置き換える
8505         '展開しないように変更
8506         '展開するか判定
8507         Dim isUrl As Boolean = False
8508         Dim ms As MatchCollection = Regex.Matches(status, "<a target=""_self"" href=""(?<url>[^""]+)""[^>]*>(?<link>(https?|shttp|ftps?)://[^<]+)</a>")
8509         For Each m As Match In ms
8510             If m.Result("${link}").EndsWith("...") Then
8511                 isUrl = True
8512                 Exit For
8513             End If
8514         Next
8515         If isUrl Then
8516             status = Regex.Replace(status, "<a target=""_self"" href=""(?<url>[^""]+)""[^>]*>(?<link>(https?|shttp|ftps?)://[^<]+)</a>", "${url}")
8517         Else
8518             status = Regex.Replace(status, "<a target=""_self"" href=""(?<url>[^""]+)""[^>]*>(?<link>(https?|shttp|ftps?)://[^<]+)</a>", "${link}")
8519         End If
8520
8521         'その他のリンク(@IDなど)を置き換える
8522         status = Regex.Replace(status, "@<a target=""_self"" href=""https?://twitter.com/(#!/)?(?<url>[^""]+)""[^>]*>(?<link>[^<]+)</a>", "@${url}")
8523         'ハッシュタグ
8524         status = Regex.Replace(status, "<a target=""_self"" href=""(?<url>[^""]+)""[^>]*>(?<link>[^<]+)</a>", "${link}")
8525         '<br>タグ除去
8526         If StatusText.Multiline Then
8527             status = Regex.Replace(status, "(\r\n|\n|\r)?<br>", vbCrLf, RegexOptions.IgnoreCase Or RegexOptions.Multiline)
8528         Else
8529             status = Regex.Replace(status, "(\r\n|\n|\r)?<br>", "", RegexOptions.IgnoreCase Or RegexOptions.Multiline)
8530         End If
8531
8532         _reply_to_id = 0
8533         _reply_to_name = ""
8534         status = status.Replace("&nbsp;", " ")
8535
8536         Return status
8537     End Function
8538
8539     Private Sub DumpPostClassToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DumpPostClassToolStripMenuItem.Click
8540         If _curPost IsNot Nothing Then
8541             DispSelectedPost(True)
8542         End If
8543     End Sub
8544
8545     Private Sub MenuItemHelp_DropDownOpening(ByVal sender As Object, ByVal e As System.EventArgs) Handles MenuItemHelp.DropDownOpening
8546         If DebugBuild OrElse My.Computer.Keyboard.CapsLock AndAlso My.Computer.Keyboard.CtrlKeyDown AndAlso My.Computer.Keyboard.ShiftKeyDown Then
8547             DebugModeToolStripMenuItem.Visible = True
8548         Else
8549             DebugModeToolStripMenuItem.Visible = False
8550         End If
8551     End Sub
8552
8553     Private Sub ToolStripMenuItemUrlAutoShorten_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItemUrlAutoShorten.CheckedChanged
8554         SettingDialog.UrlConvertAuto = ToolStripMenuItemUrlAutoShorten.Checked
8555     End Sub
8556
8557     Private Sub ContextMenuPostMode_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuPostMode.Opening
8558         ToolStripMenuItemUrlAutoShorten.Checked = SettingDialog.UrlConvertAuto
8559     End Sub
8560
8561     Private Sub TraceOutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TraceOutToolStripMenuItem.Click
8562         If TraceOutToolStripMenuItem.Checked Then
8563             TraceFlag = True
8564         Else
8565             TraceFlag = False
8566         End If
8567     End Sub
8568
8569     Private Sub TweenMain_Deactivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Deactivate
8570         '画面が非アクティブになったら、発言欄の背景色をデフォルトへ
8571         Me.StatusText_Leave(StatusText, System.EventArgs.Empty)
8572     End Sub
8573
8574     Private Sub TabRenameMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TabRenameMenuItem.Click, RenameTbMenuItem.Click
8575         If String.IsNullOrEmpty(_rclickTabName) Then Exit Sub
8576         TabRename(_rclickTabName)
8577     End Sub
8578
8579     Private Sub BitlyToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BitlyToolStripMenuItem.Click
8580         UrlConvert(UrlConverter.Bitly)
8581     End Sub
8582
8583     Private Sub JmpToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles JmpStripMenuItem.Click
8584         UrlConvert(UrlConverter.Jmp)
8585     End Sub
8586
8587
8588     Private Class GetApiInfoArgs
8589         Public tw As Twitter
8590         Public info As ApiInfo
8591     End Class
8592
8593     Private Sub GetApiInfo_Dowork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
8594         Dim args As GetApiInfoArgs = DirectCast(e.Argument, GetApiInfoArgs)
8595         e.Result = tw.GetInfoApi(args.info)
8596     End Sub
8597
8598     Private Sub ApiInfoMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ApiInfoMenuItem.Click
8599         Dim info As New ApiInfo
8600         Dim tmp As String
8601         Dim args As New GetApiInfoArgs With {.tw = tw, .info = info}
8602
8603         Using dlg As New FormInfo(Me, My.Resources.ApiInfo6, AddressOf GetApiInfo_Dowork, Nothing, args)
8604             dlg.ShowDialog()
8605             If CBool(dlg.Result) Then
8606                 tmp = My.Resources.ApiInfo1 + args.info.MaxCount.ToString() + Environment.NewLine + _
8607                     My.Resources.ApiInfo2 + args.info.RemainCount.ToString() + Environment.NewLine + _
8608                     My.Resources.ApiInfo3 + args.info.ResetTime.ToString() + Environment.NewLine + _
8609                     My.Resources.ApiInfo7 + IIf(tw.UserStreamEnabled, My.Resources.Enable, My.Resources.Disable).ToString()
8610                 SetStatusLabelUrl()
8611             Else
8612                 tmp = My.Resources.ApiInfo5
8613             End If
8614         End Using
8615
8616         MessageBox.Show(tmp, My.Resources.ApiInfo4, MessageBoxButtons.OK, MessageBoxIcon.Information)
8617     End Sub
8618
8619     Private Sub FollowCommandMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FollowCommandMenuItem.Click
8620         Dim id As String = ""
8621         If _curPost IsNot Nothing Then id = _curPost.ScreenName
8622         FollowCommand(id)
8623     End Sub
8624
8625     Private Sub FollowCommand_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
8626         Dim arg As FollowRemoveCommandArgs = DirectCast(e.Argument, FollowRemoveCommandArgs)
8627         e.Result = arg.tw.PostFollowCommand(arg.id)
8628     End Sub
8629
8630     Private Sub FollowCommand(ByVal id As String)
8631         Using inputName As New InputTabName()
8632             inputName.FormTitle = "Follow"
8633             inputName.FormDescription = My.Resources.FRMessage1
8634             inputName.TabName = id
8635             If inputName.ShowDialog() = Windows.Forms.DialogResult.OK AndAlso _
8636                Not String.IsNullOrEmpty(inputName.TabName.Trim()) Then
8637                 Dim arg As New FollowRemoveCommandArgs
8638                 arg.tw = tw
8639                 arg.id = inputName.TabName.Trim()
8640                 Using _info As New FormInfo(Me, My.Resources.FollowCommandText1, _
8641                                             AddressOf FollowCommand_DoWork, _
8642                                             Nothing, _
8643                                             arg)
8644                     _info.ShowDialog()
8645                     Dim ret As String = DirectCast(_info.Result, String)
8646                     If Not String.IsNullOrEmpty(ret) Then
8647                         MessageBox.Show(My.Resources.FRMessage2 + ret)
8648                     Else
8649                         MessageBox.Show(My.Resources.FRMessage3)
8650                     End If
8651                 End Using
8652             End If
8653         End Using
8654     End Sub
8655
8656     Private Sub RemoveCommandMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RemoveCommandMenuItem.Click
8657         Dim id As String = ""
8658         If _curPost IsNot Nothing Then id = _curPost.ScreenName
8659         RemoveCommand(id, False)
8660     End Sub
8661
8662     Private Class FollowRemoveCommandArgs
8663         Public tw As Tween.Twitter
8664         Public id As String
8665     End Class
8666
8667     Private Sub RemoveCommand_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
8668         Dim arg As FollowRemoveCommandArgs = DirectCast(e.Argument, FollowRemoveCommandArgs)
8669         e.Result = arg.tw.PostRemoveCommand(arg.id)
8670     End Sub
8671
8672     Private Sub RemoveCommand(ByVal id As String, ByVal skipInput As Boolean)
8673         Dim arg As New FollowRemoveCommandArgs
8674         arg.tw = tw
8675         arg.id = id
8676         If Not skipInput Then
8677             Using inputName As New InputTabName()
8678                 inputName.FormTitle = "Unfollow"
8679                 inputName.FormDescription = My.Resources.FRMessage1
8680                 inputName.TabName = id
8681                 If inputName.ShowDialog() = Windows.Forms.DialogResult.OK AndAlso _
8682                    Not String.IsNullOrEmpty(inputName.TabName.Trim()) Then
8683                     arg.tw = tw
8684                     arg.id = inputName.TabName.Trim()
8685                 Else
8686                     Exit Sub
8687                 End If
8688             End Using
8689         End If
8690
8691         Using _info As New FormInfo(Me, My.Resources.RemoveCommandText1, _
8692                                     AddressOf RemoveCommand_DoWork, _
8693                                     Nothing, _
8694                                     arg)
8695             _info.ShowDialog()
8696             Dim ret As String = DirectCast(_info.Result, String)
8697             If Not String.IsNullOrEmpty(ret) Then
8698                 MessageBox.Show(My.Resources.FRMessage2 + ret)
8699             Else
8700                 MessageBox.Show(My.Resources.FRMessage3)
8701             End If
8702         End Using
8703     End Sub
8704
8705     Private Sub FriendshipMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FriendshipMenuItem.Click
8706         Dim id As String = ""
8707         If _curPost IsNot Nothing Then
8708             id = _curPost.ScreenName
8709         End If
8710         ShowFriendship(id)
8711     End Sub
8712
8713     Private Class ShowFriendshipArgs
8714         Public tw As Tween.Twitter
8715         Public Class FriendshipInfo
8716             Public id As String = ""
8717             Public isFollowing As Boolean = False
8718             Public isFollowed As Boolean = False
8719             Public isError As Boolean = False
8720             Public Sub New(ByVal id As String)
8721                 Me.id = id
8722             End Sub
8723         End Class
8724         Public ids As New List(Of FriendshipInfo)
8725     End Class
8726
8727     Private Sub ShowFriendship_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
8728         Dim arg As ShowFriendshipArgs = DirectCast(e.Argument, ShowFriendshipArgs)
8729         Dim result As String = ""
8730         For Each fInfo As ShowFriendshipArgs.FriendshipInfo In arg.ids
8731             Dim rt As String = arg.tw.GetFriendshipInfo(fInfo.id, fInfo.isFollowing, fInfo.isFollowed)
8732             If Not String.IsNullOrEmpty(rt) Then
8733                 If String.IsNullOrEmpty(result) Then result = rt
8734                 fInfo.isError = True
8735             End If
8736         Next
8737         e.Result = result
8738     End Sub
8739
8740     Private Sub ShowFriendship(ByVal id As String)
8741         Dim args As New ShowFriendshipArgs
8742         args.tw = tw
8743         Using inputName As New InputTabName()
8744             inputName.FormTitle = "Show Friendships"
8745             inputName.FormDescription = My.Resources.FRMessage1
8746             inputName.TabName = id
8747             If inputName.ShowDialog() = Windows.Forms.DialogResult.OK AndAlso _
8748                Not String.IsNullOrEmpty(inputName.TabName.Trim()) Then
8749                 Dim ret As String = ""
8750                 args.ids.Add(New ShowFriendshipArgs.FriendshipInfo(inputName.TabName.Trim))
8751                 Using _info As New FormInfo(Me, My.Resources.ShowFriendshipText1, _
8752                                             AddressOf ShowFriendship_DoWork, _
8753                                             Nothing, _
8754                                             args)
8755                     _info.ShowDialog()
8756                     ret = DirectCast(_info.Result, String)
8757                 End Using
8758                 Dim result As String = ""
8759                 If String.IsNullOrEmpty(ret) Then
8760                     If args.ids(0).isFollowing Then
8761                         result = My.Resources.GetFriendshipInfo1 + System.Environment.NewLine
8762                     Else
8763                         result = My.Resources.GetFriendshipInfo2 + System.Environment.NewLine
8764                     End If
8765                     If args.ids(0).isFollowed Then
8766                         result += My.Resources.GetFriendshipInfo3
8767                     Else
8768                         result += My.Resources.GetFriendshipInfo4
8769                     End If
8770                     result = args.ids(0).id + My.Resources.GetFriendshipInfo5 + System.Environment.NewLine + result
8771                 Else
8772                     result = ret
8773                 End If
8774                 MessageBox.Show(result)
8775             End If
8776         End Using
8777     End Sub
8778
8779     Private Sub ShowFriendship(ByVal ids() As String)
8780         For Each id As String In ids
8781             Dim ret As String = ""
8782             Dim args As New ShowFriendshipArgs
8783             args.tw = tw
8784             args.ids.Add(New ShowFriendshipArgs.FriendshipInfo(id.Trim))
8785             Using _info As New FormInfo(Me, My.Resources.ShowFriendshipText1, _
8786                                         AddressOf ShowFriendship_DoWork, _
8787                                         Nothing, _
8788                                         args)
8789                 _info.ShowDialog()
8790                 ret = DirectCast(_info.Result, String)
8791             End Using
8792             Dim result As String = ""
8793             Dim fInfo As ShowFriendshipArgs.FriendshipInfo = args.ids(0)
8794             Dim ff As String = ""
8795             If String.IsNullOrEmpty(ret) Then
8796                 ff = "  "
8797                 If fInfo.isFollowing Then
8798                     ff += My.Resources.GetFriendshipInfo1
8799                 Else
8800                     ff += My.Resources.GetFriendshipInfo2
8801                 End If
8802                 ff += System.Environment.NewLine + "  "
8803                 If fInfo.isFollowed Then
8804                     ff += My.Resources.GetFriendshipInfo3
8805                 Else
8806                     ff += My.Resources.GetFriendshipInfo4
8807                 End If
8808                 result += fInfo.id + My.Resources.GetFriendshipInfo5 + System.Environment.NewLine + ff
8809                 If fInfo.isFollowing Then
8810                     If MessageBox.Show( _
8811                         My.Resources.GetFriendshipInfo7 + System.Environment.NewLine + result, My.Resources.GetFriendshipInfo8, _
8812                         MessageBoxButtons.YesNo, _
8813                         MessageBoxIcon.Question, _
8814                         MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.Yes Then
8815                         RemoveCommand(fInfo.id, True)
8816                     End If
8817                 Else
8818                     MessageBox.Show(result)
8819                 End If
8820             Else
8821                 MessageBox.Show(ret)
8822             End If
8823         Next
8824     End Sub
8825
8826     Private Sub OwnStatusMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OwnStatusMenuItem.Click
8827         doShowUserStatus(tw.Username, False)
8828         'If Not String.IsNullOrEmpty(tw.UserInfoXml) Then
8829         '    doShowUserStatus(tw.Username, False)
8830         'Else
8831         '    MessageBox.Show(My.Resources.ShowYourProfileText1, "Your status", MessageBoxButtons.OK, MessageBoxIcon.Information)
8832         '    Exit Sub
8833         'End If
8834     End Sub
8835
8836     ' TwitterIDでない固定文字列を調べる(文字列検証のみ 実際に取得はしない)
8837     ' URLから切り出した文字列を渡す
8838
8839     Public Function IsTwitterId(ByVal name As String) As Boolean
8840         Return Not Regex.Match(name, "^(about|jobs|tos|privacy)$").Success
8841     End Function
8842
8843     Private Function GetUserId() As String
8844         Dim m As Match = Regex.Match(Me._postBrowserStatusText, "^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?$")
8845         If m.Success AndAlso IsTwitterId(m.Result("${ScreenName}")) Then
8846             Return m.Result("${ScreenName}")
8847         Else
8848             Return Nothing
8849         End If
8850     End Function
8851
8852     Private Sub FollowContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FollowContextMenuItem.Click
8853         Dim name As String = GetUserId()
8854         If name IsNot Nothing Then FollowCommand(name)
8855     End Sub
8856
8857     Private Sub RemoveContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RemoveContextMenuItem.Click
8858         Dim name As String = GetUserId()
8859         If name IsNot Nothing Then RemoveCommand(name, False)
8860     End Sub
8861
8862     Private Sub FriendshipContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FriendshipContextMenuItem.Click
8863         Dim name As String = GetUserId()
8864         If name IsNot Nothing Then ShowFriendship(name)
8865     End Sub
8866
8867     Private Sub FriendshipAllMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FriendshipAllMenuItem.Click
8868         Dim ma As MatchCollection = Regex.Matches(Me.PostBrowser.DocumentText, "href=""https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?""")
8869         Dim ids As New List(Of String)
8870         For Each mu As Match In ma
8871             If mu.Result("${ScreenName}").ToLower <> tw.Username.ToLower Then
8872                 ids.Add(mu.Result("${ScreenName}"))
8873             End If
8874         Next
8875         ShowFriendship(ids.ToArray)
8876     End Sub
8877
8878     Private Sub ShowUserStatusContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ShowUserStatusContextMenuItem.Click
8879         Dim name As String = GetUserId()
8880         If name IsNot Nothing Then ShowUserStatus(name)
8881     End Sub
8882
8883     Private Sub SearchPostsDetailToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchPostsDetailToolStripMenuItem.Click
8884         Dim name As String = GetUserId()
8885         If name IsNot Nothing Then AddNewTabForUserTimeline(name)
8886     End Sub
8887
8888     Private Sub SearchAtPostsDetailToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchAtPostsDetailToolStripMenuItem.Click
8889         Dim name As String = GetUserId()
8890         If name IsNot Nothing Then AddNewTabForSearch("@" + name)
8891     End Sub
8892
8893     Private Sub IdeographicSpaceToSpaceToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IdeographicSpaceToSpaceToolStripMenuItem.Click
8894         _modifySettingCommon = True
8895     End Sub
8896
8897     Private Sub ToolStripFocusLockMenuItem_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripFocusLockMenuItem.Click
8898         _modifySettingCommon = True
8899     End Sub
8900
8901     Private Sub doQuote()
8902         'QT @id:内容
8903         '返信先情報付加
8904         If Me.ExistCurrentPost Then
8905             If _curPost.IsDm OrElse _
8906                Not StatusText.Enabled Then Exit Sub
8907
8908             If _curPost.IsProtect Then
8909                 MessageBox.Show("Protected.")
8910                 Exit Sub
8911             End If
8912             Dim rtdata As String = _curPost.Text
8913             rtdata = CreateRetweetUnofficial(rtdata)
8914
8915             StatusText.Text = " QT @" + _curPost.ScreenName + ": " + HttpUtility.HtmlDecode(rtdata)
8916             If _curPost.RetweetedId = 0 Then
8917                 _reply_to_id = _curPost.StatusId
8918             Else
8919                 _reply_to_id = _curPost.RetweetedId
8920             End If
8921             _reply_to_name = _curPost.ScreenName
8922
8923             StatusText.SelectionStart = 0
8924             StatusText.Focus()
8925         End If
8926     End Sub
8927
8928     Private Sub QuoteStripMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles QuoteStripMenuItem.Click, QtOpMenuItem.Click
8929         doQuote()
8930     End Sub
8931
8932     Private Sub SearchButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
8933         '公式検索
8934         Dim pnl As Control = DirectCast(sender, Control).Parent
8935         If pnl Is Nothing Then Exit Sub
8936         Dim tbName As String = pnl.Parent.Text
8937         Dim tb As TabClass = _statuses.Tabs(tbName)
8938         Dim cmb As ComboBox = DirectCast(pnl.Controls("comboSearch"), ComboBox)
8939         Dim cmbLang As ComboBox = DirectCast(pnl.Controls("comboLang"), ComboBox)
8940         Dim cmbusline As ComboBox = DirectCast(pnl.Controls("comboUserline"), ComboBox)
8941         cmb.Text = cmb.Text.Trim
8942         ' 検索式演算子 OR についてのみ大文字しか認識しないので強制的に大文字とする
8943         Dim Quote As Boolean = False
8944         Dim buf As New StringBuilder()
8945         Dim c As Char() = cmb.Text.ToCharArray()
8946         For cnt As Integer = 0 To cmb.Text.Length - 1
8947             If cnt > cmb.Text.Length - 4 Then
8948                 buf.Append(cmb.Text.Substring(cnt))
8949                 Exit For
8950             End If
8951             If c(cnt) = CChar("""") Then
8952                 Quote = Not Quote
8953             Else
8954                 If Not Quote AndAlso cmb.Text.Substring(cnt, 4).Equals(" or ", StringComparison.OrdinalIgnoreCase) Then
8955                     buf.Append(" OR ")
8956                     cnt += 3
8957                     Continue For
8958                 End If
8959             End If
8960             buf.Append(c(cnt))
8961         Next
8962         cmb.Text = buf.ToString()
8963
8964         tb.SearchWords = cmb.Text
8965         tb.SearchLang = cmbLang.Text
8966         If cmb.Text = "" Then
8967             DirectCast(ListTab.SelectedTab.Tag, DetailsListView).Focus()
8968             SaveConfigsTabs()
8969             Exit Sub
8970         End If
8971         If tb.IsQueryChanged Then
8972             Dim idx As Integer = DirectCast(pnl.Controls("comboSearch"), ComboBox).Items.IndexOf(tb.SearchWords)
8973             If idx > -1 Then DirectCast(pnl.Controls("comboSearch"), ComboBox).Items.RemoveAt(idx)
8974             DirectCast(pnl.Controls("comboSearch"), ComboBox).Items.Insert(0, tb.SearchWords)
8975             cmb.Text = tb.SearchWords
8976             cmb.SelectAll()
8977             Dim lst As DetailsListView = DirectCast(pnl.Parent.Tag, DetailsListView)
8978             lst.VirtualListSize = 0
8979             lst.Items.Clear()
8980             _statuses.ClearTabIds(tbName)
8981             SaveConfigsTabs()   '検索条件の保存
8982         End If
8983
8984         GetTimeline(WORKERTYPE.PublicSearch, 1, 0, tbName)
8985         DirectCast(ListTab.SelectedTab.Tag, DetailsListView).Focus()
8986     End Sub
8987
8988     Private Sub RefreshMoreStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RefreshMoreStripMenuItem.Click, RefreshPrevOpMenuItem.Click
8989         'もっと前を取得
8990         DoRefreshMore()
8991     End Sub
8992
8993     Private Sub UndoRemoveTabMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UndoRemoveTabMenuItem.Click
8994         If _statuses.RemovedTab.Count = 0 Then
8995             MessageBox.Show("There isn't removed tab.", "Undo", MessageBoxButtons.OK, MessageBoxIcon.Information)
8996             Exit Sub
8997         Else
8998             Dim tb As TabClass = _statuses.RemovedTab.Pop()
8999             Dim renamed As String = tb.TabName
9000             For i As Integer = 1 To Integer.MaxValue
9001                 If Not _statuses.ContainsTab(renamed) Then Exit For
9002                 renamed = tb.TabName + "(" + i.ToString + ")"
9003             Next
9004             tb.TabName = renamed
9005             _statuses.Tabs.Add(renamed, tb)
9006             AddNewTab(renamed, False, tb.TabType, tb.ListInfo)
9007             ListTab.SelectedIndex = ListTab.TabPages.Count - 1
9008             SaveConfigsTabs()
9009         End If
9010     End Sub
9011
9012     Private Sub doMoveToRTHome()
9013         If _curList.SelectedIndices.Count > 0 Then
9014             Dim post As PostClass = GetCurTabPost(_curList.SelectedIndices(0))
9015             If post.RetweetedId > 0 Then
9016                 OpenUriAsync("http://twitter.com/" + GetCurTabPost(_curList.SelectedIndices(0)).RetweetedBy)
9017             End If
9018         End If
9019     End Sub
9020
9021     Private Sub MoveToRTHomeMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MoveToRTHomeMenuItem.Click, OpenRterHomeMenuItem.Click
9022         doMoveToRTHome()
9023     End Sub
9024
9025     Private Sub IdFilterAddMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IdFilterAddMenuItem.Click
9026         Dim name As String = GetUserId()
9027         If name IsNot Nothing Then
9028             Dim tabName As String = ""
9029
9030             '未選択なら処理終了
9031             If _curList.SelectedIndices.Count = 0 Then Exit Sub
9032
9033             'タブ選択(or追加)
9034             If Not SelectTab(tabName) Then Exit Sub
9035
9036             Dim mv As Boolean = False
9037             Dim mk As Boolean = False
9038             MoveOrCopy(mv, mk)
9039
9040             Dim fc As New FiltersClass
9041             fc.NameFilter = name
9042             fc.SearchBoth = True
9043             fc.MoveFrom = mv
9044             fc.SetMark = mk
9045             fc.UseRegex = False
9046             fc.SearchUrl = False
9047             _statuses.Tabs(tabName).AddFilter(fc)
9048
9049             Try
9050                 Me.Cursor = Cursors.WaitCursor
9051                 _itemCache = Nothing
9052                 _postCache = Nothing
9053                 _curPost = Nothing
9054                 _curItemIndex = -1
9055                 _statuses.FilterAll()
9056                 For Each tb As TabPage In ListTab.TabPages
9057                     DirectCast(tb.Tag, DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
9058                     If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
9059                         If SettingDialog.TabIconDisp Then
9060                             tb.ImageIndex = 0
9061                         End If
9062                     Else
9063                         If SettingDialog.TabIconDisp Then
9064                             tb.ImageIndex = -1
9065                         End If
9066                     End If
9067                 Next
9068                 If Not SettingDialog.TabIconDisp Then ListTab.Refresh()
9069             Finally
9070                 Me.Cursor = Cursors.Default
9071             End Try
9072             SaveConfigsTabs()
9073         End If
9074     End Sub
9075
9076     Private Sub ListManageUserContextToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListManageUserContextToolStripMenuItem.Click, ListManageMenuItem.Click, ListManageUserContextToolStripMenuItem2.Click, ListManageUserContextToolStripMenuItem3.Click
9077         Dim user As String
9078
9079         Dim menuItem As ToolStripMenuItem = DirectCast(sender, ToolStripMenuItem)
9080
9081         If menuItem.Owner Is Me.ContextMenuPostBrowser Then
9082             user = GetUserId()
9083             If user Is Nothing Then Return
9084         ElseIf Me._curPost IsNot Nothing Then
9085             user = Me._curPost.ScreenName
9086         Else
9087             Return
9088         End If
9089
9090         Dim list As ListElement = Nothing
9091
9092         If TabInformations.GetInstance().SubscribableLists.Count = 0 Then
9093             Dim res As String = Me.tw.GetListsApi()
9094
9095             If res <> "" Then
9096                 MessageBox.Show("Failed to get lists. (" + res + ")")
9097                 Return
9098             End If
9099         End If
9100
9101         Using listSelectForm As New MyLists(user, Me.tw)
9102             listSelectForm.ShowDialog(Me)
9103         End Using
9104     End Sub
9105
9106     Private Sub SearchControls_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs)
9107         Dim pnl As Control = DirectCast(sender, Control)
9108         For Each ctl As Control In pnl.Controls
9109             ctl.TabStop = True
9110         Next
9111     End Sub
9112
9113     Private Sub SearchControls_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs)
9114         Dim pnl As Control = DirectCast(sender, Control)
9115         For Each ctl As Control In pnl.Controls
9116             ctl.TabStop = False
9117         Next
9118     End Sub
9119
9120     Private Sub PublicSearchQueryMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PublicSearchQueryMenuItem.Click
9121         If ListTab.SelectedTab IsNot Nothing Then
9122             If _statuses.Tabs(ListTab.SelectedTab.Text).TabType <> TabUsageType.PublicSearch Then Exit Sub
9123             ListTab.SelectedTab.Controls("panelSearch").Controls("comboSearch").Focus()
9124         End If
9125     End Sub
9126
9127     Private Sub UseHashtagMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UseHashtagMenuItem.Click
9128         Dim m As Match = Regex.Match(Me._postBrowserStatusText, "^https?://twitter.com/search\?q=%23(?<hash>[a-zA-Z0-9_]+)$")
9129         If m.Success Then
9130             HashMgr.SetPermanentHash("#" + m.Result("${hash}"))
9131             HashStripSplitButton.Text = HashMgr.UseHash
9132             HashToggleMenuItem.Checked = True
9133             HashToggleToolStripMenuItem.Checked = True
9134             '使用ハッシュタグとして設定
9135             _modifySettingCommon = True
9136         End If
9137     End Sub
9138
9139     Private Sub StatusLabel_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusLabel.DoubleClick
9140         MessageBox.Show(StatusLabel.TextHistory, "Logs", MessageBoxButtons.OK, MessageBoxIcon.None)
9141     End Sub
9142
9143     Private Sub HashManageMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles HashManageMenuItem.Click, HashManageToolStripMenuItem.Click
9144         Dim rslt As DialogResult
9145         Try
9146             rslt = HashMgr.ShowDialog()
9147         Catch ex As Exception
9148             Exit Sub
9149         End Try
9150         Me.TopMost = SettingDialog.AlwaysTop
9151         If rslt = Windows.Forms.DialogResult.Cancel Then Exit Sub
9152         If HashMgr.UseHash <> "" Then
9153             HashStripSplitButton.Text = HashMgr.UseHash
9154             HashToggleMenuItem.Checked = True
9155             HashToggleToolStripMenuItem.Checked = True
9156         Else
9157             HashStripSplitButton.Text = "#[-]"
9158             HashToggleMenuItem.Checked = False
9159             HashToggleToolStripMenuItem.Checked = False
9160         End If
9161         'If HashMgr.IsInsert AndAlso HashMgr.UseHash <> "" Then
9162         '    Dim sidx As Integer = StatusText.SelectionStart
9163         '    Dim hash As String = HashMgr.UseHash + " "
9164         '    If sidx > 0 Then
9165         '        If StatusText.Text.Substring(sidx - 1, 1) <> " " Then
9166         '            hash = " " + hash
9167         '        End If
9168         '    End If
9169         '    StatusText.Text = StatusText.Text.Insert(sidx, hash)
9170         '    sidx += hash.Length
9171         '    StatusText.SelectionStart = sidx
9172         '    StatusText.Focus()
9173         'End If
9174         _modifySettingCommon = True
9175         Me.StatusText_TextChanged(Nothing, Nothing)
9176     End Sub
9177
9178     Private Sub HashToggleMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles HashToggleMenuItem.Click, HashToggleToolStripMenuItem.Click
9179         HashMgr.ToggleHash()
9180         If HashMgr.UseHash <> "" Then
9181             HashStripSplitButton.Text = HashMgr.UseHash
9182             HashToggleMenuItem.Checked = True
9183             HashToggleToolStripMenuItem.Checked = True
9184         Else
9185             HashStripSplitButton.Text = "#[-]"
9186             HashToggleMenuItem.Checked = False
9187             HashToggleToolStripMenuItem.Checked = False
9188         End If
9189         _modifySettingCommon = True
9190         Me.StatusText_TextChanged(Nothing, Nothing)
9191     End Sub
9192
9193     Private Sub HashStripSplitButton_ButtonClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles HashStripSplitButton.ButtonClick
9194         HashToggleMenuItem_Click(Nothing, Nothing)
9195     End Sub
9196
9197     Private Sub MenuItemOperate_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemOperate.DropDownOpening
9198         If ListTab.SelectedTab Is Nothing Then Exit Sub
9199         If _statuses Is Nothing OrElse _statuses.Tabs Is Nothing OrElse Not _statuses.Tabs.ContainsKey(ListTab.SelectedTab.Text) Then Exit Sub
9200         If Not Me.ExistCurrentPost Then
9201             Me.ReplyOpMenuItem.Enabled = False
9202             Me.ReplyAllOpMenuItem.Enabled = False
9203             Me.DmOpMenuItem.Enabled = False
9204             Me.ShowProfMenuItem.Enabled = False
9205             Me.ShowUserTimelineToolStripMenuItem.Enabled = False
9206             Me.ListManageMenuItem.Enabled = False
9207             Me.OpenFavOpMenuItem.Enabled = False
9208             Me.CreateTabRuleOpMenuItem.Enabled = False
9209             Me.CreateIdRuleOpMenuItem.Enabled = False
9210             Me.ReadOpMenuItem.Enabled = False
9211             Me.UnreadOpMenuItem.Enabled = False
9212         Else
9213             Me.ReplyOpMenuItem.Enabled = True
9214             Me.ReplyAllOpMenuItem.Enabled = True
9215             Me.DmOpMenuItem.Enabled = True
9216             Me.ShowProfMenuItem.Enabled = True
9217             Me.ShowUserTimelineToolStripMenuItem.Enabled = True
9218             Me.ListManageMenuItem.Enabled = True
9219             Me.OpenFavOpMenuItem.Enabled = True
9220             Me.CreateTabRuleOpMenuItem.Enabled = True
9221             Me.CreateIdRuleOpMenuItem.Enabled = True
9222             Me.ReadOpMenuItem.Enabled = True
9223             Me.UnreadOpMenuItem.Enabled = True
9224         End If
9225
9226         If _statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.DirectMessage OrElse Not Me.ExistCurrentPost OrElse _curPost.IsDm Then
9227             Me.FavOpMenuItem.Enabled = False
9228             Me.UnFavOpMenuItem.Enabled = False
9229             Me.OpenStatusOpMenuItem.Enabled = False
9230             Me.OpenFavotterOpMenuItem.Enabled = False
9231             Me.ShowRelatedStatusesMenuItem2.Enabled = False
9232             Me.RtOpMenuItem.Enabled = False
9233             Me.RtUnOpMenuItem.Enabled = False
9234             Me.QtOpMenuItem.Enabled = False
9235             Me.FavoriteRetweetMenuItem.Enabled = False
9236             Me.FavoriteRetweetUnofficialMenuItem.Enabled = False
9237             If Me.ExistCurrentPost AndAlso _curPost.IsDm Then Me.DelOpMenuItem.Enabled = True
9238         Else
9239             Me.FavOpMenuItem.Enabled = True
9240             Me.UnFavOpMenuItem.Enabled = True
9241             Me.OpenStatusOpMenuItem.Enabled = True
9242             Me.OpenFavotterOpMenuItem.Enabled = True
9243             Me.ShowRelatedStatusesMenuItem2.Enabled = True  'PublicSearchの時問題出るかも
9244
9245             If _curPost.IsMe Then
9246                 Me.RtOpMenuItem.Enabled = False
9247                 Me.FavoriteRetweetMenuItem.Enabled = False
9248                 Me.DelOpMenuItem.Enabled = True
9249             Else
9250                 Me.DelOpMenuItem.Enabled = False
9251                 If _curPost.IsProtect Then
9252                     Me.RtOpMenuItem.Enabled = False
9253                     Me.RtUnOpMenuItem.Enabled = False
9254                     Me.QtOpMenuItem.Enabled = False
9255                     Me.FavoriteRetweetMenuItem.Enabled = False
9256                     Me.FavoriteRetweetUnofficialMenuItem.Enabled = False
9257                 Else
9258                     Me.RtOpMenuItem.Enabled = True
9259                     Me.RtUnOpMenuItem.Enabled = True
9260                     Me.QtOpMenuItem.Enabled = True
9261                     Me.FavoriteRetweetMenuItem.Enabled = True
9262                     Me.FavoriteRetweetUnofficialMenuItem.Enabled = True
9263                 End If
9264             End If
9265         End If
9266
9267         If _statuses.Tabs(ListTab.SelectedTab.Text).TabType <> TabUsageType.Favorites Then
9268             Me.RefreshPrevOpMenuItem.Enabled = True
9269         Else
9270             Me.RefreshPrevOpMenuItem.Enabled = False
9271         End If
9272         If _statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.PublicSearch _
9273                             OrElse Not Me.ExistCurrentPost _
9274                             OrElse Not _curPost.InReplyToStatusId > 0 Then
9275             OpenRepSourceOpMenuItem.Enabled = False
9276         Else
9277             OpenRepSourceOpMenuItem.Enabled = True
9278         End If
9279         If Not Me.ExistCurrentPost OrElse _curPost.RetweetedBy = "" Then
9280             OpenRterHomeMenuItem.Enabled = False
9281         Else
9282             OpenRterHomeMenuItem.Enabled = True
9283         End If
9284     End Sub
9285
9286     Private Sub MenuItemTab_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemTab.DropDownOpening
9287         ContextMenuTabProperty_Opening(sender, Nothing)
9288     End Sub
9289
9290     Public ReadOnly Property TwitterInstance() As Twitter
9291         Get
9292             Return tw
9293         End Get
9294     End Property
9295
9296
9297     Private Sub SplitContainer3_SplitterMoved(ByVal sender As System.Object, ByVal e As System.Windows.Forms.SplitterEventArgs) Handles SplitContainer3.SplitterMoved
9298         If Me.WindowState = FormWindowState.Normal AndAlso Not _initialLayout Then
9299             _mySpDis3 = SplitContainer3.SplitterDistance
9300             _modifySettingLocal = True
9301         End If
9302     End Sub
9303
9304     Private Sub MenuItemEdit_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemEdit.DropDownOpening
9305         If _statuses.RemovedTab.Count = 0 Then
9306             UndoRemoveTabMenuItem.Enabled = False
9307         Else
9308             UndoRemoveTabMenuItem.Enabled = True
9309         End If
9310         If ListTab.SelectedTab IsNot Nothing Then
9311             If _statuses.Tabs(ListTab.SelectedTab.Text).TabType = TabUsageType.PublicSearch Then
9312                 PublicSearchQueryMenuItem.Enabled = True
9313             Else
9314                 PublicSearchQueryMenuItem.Enabled = False
9315             End If
9316         Else
9317             PublicSearchQueryMenuItem.Enabled = False
9318         End If
9319         If Not Me.ExistCurrentPost Then
9320             Me.CopySTOTMenuItem.Enabled = False
9321             Me.CopyURLMenuItem.Enabled = False
9322             Me.CopyUserIdStripMenuItem.Enabled = False
9323         Else
9324             Me.CopySTOTMenuItem.Enabled = True
9325             Me.CopyURLMenuItem.Enabled = True
9326             Me.CopyUserIdStripMenuItem.Enabled = True
9327             If _curPost.IsDm Then Me.CopyURLMenuItem.Enabled = False
9328             If _curPost.IsProtect Then Me.CopySTOTMenuItem.Enabled = False
9329         End If
9330     End Sub
9331
9332     Private Sub NotifyIcon1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.MouseMove
9333         SetNotifyIconText()
9334     End Sub
9335
9336     Private Sub UserStatusToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UserStatusToolStripMenuItem.Click
9337         Dim id As String = ""
9338         If _curPost IsNot Nothing Then
9339             id = _curPost.ScreenName
9340         End If
9341         ShowUserStatus(id)
9342     End Sub
9343
9344     Private Class GetUserInfoArgs
9345         Public tw As Tween.Twitter
9346         Public id As String
9347         Public user As TwitterDataModel.User
9348     End Class
9349
9350     Private Sub GetUserInfo_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
9351         Dim args As GetUserInfoArgs = DirectCast(e.Argument, GetUserInfoArgs)
9352         e.Result = args.tw.GetUserInfo(args.id, args.user)
9353     End Sub
9354
9355     Private Overloads Sub doShowUserStatus(ByVal id As String, ByVal ShowInputDialog As Boolean)
9356         Dim result As String = ""
9357         Dim user As TwitterDataModel.User = Nothing
9358         Dim args As New GetUserInfoArgs
9359         If ShowInputDialog Then
9360             Using inputName As New InputTabName()
9361                 inputName.FormTitle = "Show UserStatus"
9362                 inputName.FormDescription = My.Resources.FRMessage1
9363                 inputName.TabName = id
9364                 If inputName.ShowDialog() = Windows.Forms.DialogResult.OK AndAlso _
9365                    Not String.IsNullOrEmpty(inputName.TabName.Trim()) Then
9366                     id = inputName.TabName.Trim
9367                     args.tw = tw
9368                     args.id = id
9369                     args.user = user
9370                     Using _info As New FormInfo(Me, My.Resources.doShowUserStatusText1, _
9371                                                 AddressOf GetUserInfo_DoWork, _
9372                                                 Nothing, _
9373                                                 args)
9374                         _info.ShowDialog()
9375                         Dim ret As String = DirectCast(_info.Result, String)
9376                         If String.IsNullOrEmpty(ret) Then
9377                             doShowUserStatus(args.user)
9378                         Else
9379                             MessageBox.Show(ret)
9380                         End If
9381                     End Using
9382                 End If
9383             End Using
9384         Else
9385             args.tw = tw
9386             args.id = id
9387             args.user = user
9388             Using _info As New FormInfo(Me, My.Resources.doShowUserStatusText1, _
9389                                         AddressOf GetUserInfo_DoWork, _
9390                                         Nothing, _
9391                                         args)
9392                 _info.ShowDialog()
9393                 Dim ret As String = DirectCast(_info.Result, String)
9394                 If String.IsNullOrEmpty(ret) Then
9395                     doShowUserStatus(args.user)
9396                 Else
9397                     MessageBox.Show(ret)
9398                 End If
9399             End Using
9400         End If
9401     End Sub
9402
9403     Private Overloads Sub doShowUserStatus(ByVal user As TwitterDataModel.User)
9404         Using userinfo As New ShowUserInfo()
9405             userinfo.Owner = Me
9406             userinfo.User = user
9407             userinfo.ShowDialog(Me)
9408             Me.Activate()
9409         End Using
9410     End Sub
9411
9412     Private Overloads Sub ShowUserStatus(ByVal id As String, ByVal ShowInputDialog As Boolean)
9413         doShowUserStatus(id, ShowInputDialog)
9414     End Sub
9415
9416     Private Overloads Sub ShowUserStatus(ByVal id As String)
9417         doShowUserStatus(id, True)
9418     End Sub
9419
9420     Private Sub FollowToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FollowToolStripMenuItem.Click
9421         If NameLabel.Tag IsNot Nothing Then
9422             Dim id As String = DirectCast(NameLabel.Tag, String)
9423             If id <> tw.Username Then
9424                 FollowCommand(id)
9425             End If
9426         End If
9427     End Sub
9428
9429     Private Sub UnFollowToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UnFollowToolStripMenuItem.Click
9430         If NameLabel.Tag IsNot Nothing Then
9431             Dim id As String = DirectCast(NameLabel.Tag, String)
9432             If id <> tw.Username Then
9433                 RemoveCommand(id, False)
9434             End If
9435         End If
9436     End Sub
9437
9438     Private Sub ShowFriendShipToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ShowFriendShipToolStripMenuItem.Click
9439         If NameLabel.Tag IsNot Nothing Then
9440             Dim id As String = DirectCast(NameLabel.Tag, String)
9441             If id <> tw.Username Then
9442                 ShowFriendship(id)
9443             End If
9444         End If
9445     End Sub
9446
9447     Private Sub ShowUserStatusToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ShowUserStatusToolStripMenuItem.Click
9448         If NameLabel.Tag IsNot Nothing Then
9449             Dim id As String = DirectCast(NameLabel.Tag, String)
9450             ShowUserStatus(id, False)
9451         End If
9452     End Sub
9453
9454     Private Sub SearchPostsDetailNameToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchPostsDetailNameToolStripMenuItem.Click
9455         If NameLabel.Tag IsNot Nothing Then
9456             Dim id As String = DirectCast(NameLabel.Tag, String)
9457             AddNewTabForUserTimeline(id)
9458         End If
9459     End Sub
9460
9461     Private Sub SearchAtPostsDetailNameToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchAtPostsDetailNameToolStripMenuItem.Click
9462         If NameLabel.Tag IsNot Nothing Then
9463             Dim id As String = DirectCast(NameLabel.Tag, String)
9464             AddNewTabForSearch("@" + id)
9465         End If
9466     End Sub
9467
9468     Private Sub ShowProfileMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ShowProfileMenuItem.Click, ShowProfMenuItem.Click
9469         If _curPost IsNot Nothing Then
9470             ShowUserStatus(_curPost.ScreenName, False)
9471         End If
9472     End Sub
9473
9474     Private Sub GetRetweet_DoWork(ByVal sender As Object, ByVal e As ComponentModel.DoWorkEventArgs)
9475         Dim counter As Integer = 0
9476
9477         Dim statusid As Long
9478         If _curPost.RetweetedId > 0 Then
9479             statusid = _curPost.RetweetedId
9480         Else
9481             statusid = _curPost.StatusId
9482         End If
9483         tw.GetStatus_Retweeted_Count(statusid, counter)
9484
9485         e.Result = counter
9486     End Sub
9487
9488     Private Sub RtCountMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RtCountMenuItem.Click
9489         If Me.ExistCurrentPost Then
9490             Using _info As New FormInfo(Me, My.Resources.RtCountMenuItem_ClickText1, _
9491                             AddressOf GetRetweet_DoWork)
9492                 Dim retweet_count As Integer = 0
9493
9494                 ' ダイアログ表示
9495                 _info.ShowDialog()
9496                 retweet_count = CType(_info.Result, Integer)
9497                 If retweet_count < 0 Then
9498                     MessageBox.Show(My.Resources.RtCountText2)
9499                 Else
9500                     MessageBox.Show(retweet_count.ToString + My.Resources.RtCountText1)
9501                 End If
9502             End Using
9503         End If
9504     End Sub
9505
9506     Private WithEvents _hookGlobalHotkey As HookGlobalHotkey
9507     Public Sub New()
9508         _instance = Me
9509         _hookGlobalHotkey = New HookGlobalHotkey(Me)
9510         ' この呼び出しは、Windows フォーム デザイナで必要です。
9511         InitializeComponent()
9512
9513         ' InitializeComponent() 呼び出しの後で初期化を追加します。
9514
9515         Me._apiGauge.Control.Size = New Size(70, 22)
9516         Me._apiGauge.Control.Margin = New Padding(0, 3, 0, 2)
9517         Me._apiGauge.GaugeHeight = 8
9518         AddHandler Me._apiGauge.Control.DoubleClick, AddressOf Me.ApiInfoMenuItem_Click
9519         Me.StatusStrip1.Items.Insert(2, Me._apiGauge)
9520     End Sub
9521
9522     Private Sub _hookGlobalHotkey_HotkeyPressed(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles _hookGlobalHotkey.HotkeyPressed
9523         If (Me.WindowState = FormWindowState.Normal OrElse Me.WindowState = FormWindowState.Maximized) AndAlso Me.Visible AndAlso Form.ActiveForm Is Me Then
9524             'アイコン化
9525             Me.Visible = False
9526         ElseIf Form.ActiveForm Is Nothing Then
9527             Me.Visible = True
9528             If Me.WindowState = FormWindowState.Minimized Then Me.WindowState = FormWindowState.Normal
9529             Me.Activate()
9530             Me.StatusText.Focus()
9531         End If
9532     End Sub
9533
9534     Private Sub UserPicture_MouseEnter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UserPicture.MouseEnter
9535         Me.UserPicture.Cursor = Cursors.Hand
9536     End Sub
9537
9538     Private Sub UserPicture_MouseLeave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UserPicture.MouseLeave
9539         Me.UserPicture.Cursor = Cursors.Default
9540     End Sub
9541
9542     Private Sub UserPicture_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UserPicture.DoubleClick
9543         If NameLabel.Tag IsNot Nothing Then
9544             OpenUriAsync("http://twitter.com/" + NameLabel.Tag.ToString)
9545         End If
9546     End Sub
9547
9548     Private Sub SplitContainer2_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles SplitContainer2.MouseDoubleClick
9549         Me.MultiLineMenuItem.PerformClick()
9550     End Sub
9551
9552     Public ReadOnly Property CurPost As PostClass
9553         Get
9554             Return _curPost
9555         End Get
9556     End Property
9557
9558     Public ReadOnly Property IsPreviewEnable As Boolean
9559         Get
9560             Return SettingDialog.PreviewEnable
9561         End Get
9562     End Property
9563
9564 #Region "画像投稿"
9565     Private Sub ImageSelectMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ImageSelectMenuItem.Click
9566         If ImageSelectionPanel.Visible = True Then
9567             ImagefilePathText.CausesValidation = False
9568             TimelinePanel.Visible = True
9569             TimelinePanel.Enabled = True
9570             ImageSelectionPanel.Visible = False
9571             ImageSelectionPanel.Enabled = False
9572             DirectCast(ListTab.SelectedTab.Tag, DetailsListView).Focus()
9573             ImagefilePathText.CausesValidation = True
9574         Else
9575             ImageSelectionPanel.Visible = True
9576             ImageSelectionPanel.Enabled = True
9577             TimelinePanel.Visible = False
9578             TimelinePanel.Enabled = False
9579             ImagefilePathText.Focus()
9580         End If
9581     End Sub
9582
9583     Private Sub FilePickButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FilePickButton.Click
9584         If String.IsNullOrEmpty(Me.ImageService) Then Exit Sub
9585         OpenFileDialog1.Filter = Me.pictureService(Me.ImageService).GetFileOpenDialogFilter()
9586         OpenFileDialog1.Title = My.Resources.PickPictureDialog1
9587         OpenFileDialog1.FileName = ""
9588
9589         Try
9590             Me.AllowDrop = False
9591             If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub
9592         Finally
9593             Me.AllowDrop = True
9594         End Try
9595
9596         ImagefilePathText.Text = OpenFileDialog1.FileName
9597         ImageFromSelectedFile()
9598     End Sub
9599
9600     Private Sub ImagefilePathText_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ImagefilePathText.Validating
9601         If ImageCancelButton.Focused Then
9602             ImagefilePathText.CausesValidation = False
9603             Exit Sub
9604         End If
9605         ImagefilePathText.Text = Trim(ImagefilePathText.Text)
9606         If ImagefilePathText.Text = "" Then
9607             ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9608             ImageSelectedPicture.Tag = UploadFileType.Invalid
9609         Else
9610             ImageFromSelectedFile()
9611         End If
9612     End Sub
9613
9614     Private Sub ImageFromSelectedFile()
9615         Try
9616             If String.IsNullOrEmpty(Trim(ImagefilePathText.Text)) OrElse String.IsNullOrEmpty(Me.ImageService) Then
9617                 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9618                 ImageSelectedPicture.Tag = UploadFileType.Invalid
9619                 ImagefilePathText.Text = ""
9620                 Exit Sub
9621             End If
9622
9623             Dim fl As New FileInfo(Trim(ImagefilePathText.Text))
9624             If Not Me.pictureService(Me.ImageService).CheckValidExtension(fl.Extension) Then
9625                 '画像以外の形式
9626                 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9627                 ImageSelectedPicture.Tag = UploadFileType.Invalid
9628                 ImagefilePathText.Text = ""
9629                 Exit Sub
9630             End If
9631
9632             If Not Me.pictureService(Me.ImageService).CheckValidFilesize(fl.Extension, fl.Length) Then
9633                 ' ファイルサイズが大きすぎる
9634                 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9635                 ImageSelectedPicture.Tag = UploadFileType.Invalid
9636                 ImagefilePathText.Text = ""
9637                 MessageBox.Show("File is too large.")
9638                 Exit Sub
9639             End If
9640
9641             Select Case Me.pictureService(Me.ImageService).GetFileType(fl.Extension)
9642                 Case UploadFileType.Invalid
9643                     ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9644                     ImageSelectedPicture.Tag = UploadFileType.Invalid
9645                     ImagefilePathText.Text = ""
9646                 Case UploadFileType.Picture
9647                     Dim img As Image = Nothing
9648                     Using fs As New FileStream(ImagefilePathText.Text, FileMode.Open, FileAccess.Read)
9649                         img = Image.FromStream(fs)
9650                         fs.Close()
9651                     End Using
9652                     ImageSelectedPicture.Image = (New HttpVarious).CheckValidImage( _
9653                                 img, _
9654                                 img.Width, _
9655                                 img.Height)
9656                     ImageSelectedPicture.Tag = UploadFileType.Picture
9657                 Case UploadFileType.MultiMedia
9658                     ImageSelectedPicture.Image = My.Resources.MultiMediaImage
9659                     ImageSelectedPicture.Tag = UploadFileType.MultiMedia
9660                 Case Else
9661                     ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9662                     ImageSelectedPicture.Tag = UploadFileType.Invalid
9663                     ImagefilePathText.Text = ""
9664             End Select
9665
9666         Catch ex As FileNotFoundException
9667             ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9668             ImageSelectedPicture.Tag = UploadFileType.Invalid
9669             ImagefilePathText.Text = ""
9670             MessageBox.Show("File not found.")
9671         Catch ex As Exception
9672             ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9673             ImageSelectedPicture.Tag = UploadFileType.Invalid
9674             ImagefilePathText.Text = ""
9675             MessageBox.Show("The type of this file is not image.")
9676         End Try
9677     End Sub
9678
9679     Private Sub ImageSelection_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles _
9680         ImagefilePathText.KeyDown, _
9681         FilePickButton.KeyDown, _
9682         ImageServiceCombo.KeyDown
9683         If e.KeyCode = Keys.Escape Then
9684             ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9685             ImageSelectedPicture.Tag = UploadFileType.Invalid
9686             TimelinePanel.Visible = True
9687             TimelinePanel.Enabled = True
9688             ImageSelectionPanel.Visible = False
9689             ImageSelectionPanel.Enabled = False
9690             DirectCast(ListTab.SelectedTab.Tag, DetailsListView).Focus()
9691             ImagefilePathText.CausesValidation = True
9692         End If
9693     End Sub
9694
9695     Private Sub ImageSelection_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles _
9696     ImagefilePathText.KeyPress, _
9697     FilePickButton.KeyPress, _
9698     ImageServiceCombo.KeyPress
9699         If Convert.ToInt32(e.KeyChar) = &H1B Then
9700             ImagefilePathText.CausesValidation = False
9701             e.Handled = True
9702         End If
9703     End Sub
9704
9705     Private Sub ImageSelection_PreviewKeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles _
9706     ImagefilePathText.PreviewKeyDown, _
9707     FilePickButton.PreviewKeyDown, _
9708     ImageServiceCombo.PreviewKeyDown
9709         If e.KeyCode = Keys.Escape Then
9710             ImagefilePathText.CausesValidation = False
9711         End If
9712     End Sub
9713
9714     Private Sub SetImageServiceCombo()
9715         Dim svc As String = ""
9716         If ImageServiceCombo.SelectedIndex > -1 Then svc = ImageServiceCombo.SelectedItem.ToString
9717         ImageServiceCombo.Items.Clear()
9718         If SettingDialog.IsOAuth Then
9719             ImageServiceCombo.Items.Add("TwitPic")
9720             ImageServiceCombo.Items.Add("img.ly")
9721             ImageServiceCombo.Items.Add("yfrog")
9722             ImageServiceCombo.Items.Add("Plixi")
9723         Else
9724             ImageServiceCombo.Items.Add("")
9725             Exit Sub
9726         End If
9727         'ImageServiceCombo.Items.Add("TwitVideo")
9728         If svc = "" Then
9729             ImageServiceCombo.SelectedIndex = 0
9730         Else
9731             Dim idx As Integer = ImageServiceCombo.Items.IndexOf(svc)
9732             If idx = -1 Then
9733                 ImageServiceCombo.SelectedIndex = 0
9734             Else
9735                 ImageServiceCombo.SelectedIndex = idx
9736             End If
9737         End If
9738     End Sub
9739
9740     Private ReadOnly Property ImageService() As String
9741         Get
9742             Return CStr(ImageServiceCombo.SelectedItem)
9743         End Get
9744     End Property
9745
9746     Private Sub ImageCancelButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ImageCancelButton.Click
9747         ImagefilePathText.CausesValidation = False
9748         TimelinePanel.Visible = True
9749         TimelinePanel.Enabled = True
9750         ImageSelectionPanel.Visible = False
9751         ImageSelectionPanel.Enabled = False
9752         DirectCast(ListTab.SelectedTab.Tag, DetailsListView).Focus()
9753         ImagefilePathText.CausesValidation = True
9754     End Sub
9755
9756     Private Sub ImageServiceCombo_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ImageServiceCombo.SelectedIndexChanged
9757         If ImageSelectedPicture.Tag IsNot Nothing AndAlso Not String.IsNullOrEmpty(Me.ImageService) Then
9758             Try
9759                 Dim fi As New FileInfo(ImagefilePathText.Text.Trim)
9760                 If Not Me.pictureService(Me.ImageService).CheckValidFilesize(fi.Extension, fi.Length) Then
9761                     ImagefilePathText.Text = ""
9762                     ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage
9763                     ImageSelectedPicture.Tag = UploadFileType.Invalid
9764                 End If
9765             Catch ex As Exception
9766
9767             End Try
9768             _modifySettingCommon = True
9769             SaveConfigsAll(False)
9770         End If
9771     End Sub
9772 #End Region
9773
9774     Private Sub ListManageToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListManageToolStripMenuItem.Click
9775         Using form As New ListManage(tw)
9776             form.ShowDialog(Me)
9777         End Using
9778     End Sub
9779
9780     Public WriteOnly Property ModifySettingCommon() As Boolean
9781         Set(ByVal value As Boolean)
9782             _modifySettingCommon = value
9783         End Set
9784     End Property
9785
9786     Public WriteOnly Property ModifySettingLocal() As Boolean
9787         Set(ByVal value As Boolean)
9788             _modifySettingLocal = value
9789         End Set
9790     End Property
9791
9792     Public WriteOnly Property ModifySettingAtId() As Boolean
9793         Set(ByVal value As Boolean)
9794             _modifySettingAtId = value
9795         End Set
9796     End Property
9797
9798     Private Sub SourceLinkLabel_LinkClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles SourceLinkLabel.LinkClicked
9799         Dim link As String = CType(SourceLinkLabel.Tag, String)
9800         If Not String.IsNullOrEmpty(link) Then
9801             OpenUriAsync(link)
9802         End If
9803     End Sub
9804
9805     Private Sub SourceLinkLabel_MouseEnter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SourceLinkLabel.MouseEnter
9806         Dim link As String = CType(SourceLinkLabel.Tag, String)
9807         If Not String.IsNullOrEmpty(link) Then
9808             StatusLabelUrl.Text = link
9809         End If
9810     End Sub
9811
9812     Private Sub SourceLinkLabel_MouseLeave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SourceLinkLabel.MouseLeave
9813         SetStatusLabelUrl()
9814     End Sub
9815
9816     Private Sub MenuItemCommand_DropDownOpening(ByVal sender As Object, ByVal e As System.EventArgs) Handles MenuItemCommand.DropDownOpening
9817         If Me.ExistCurrentPost AndAlso Not _curPost.IsDm Then
9818             RtCountMenuItem.Enabled = True
9819         Else
9820             RtCountMenuItem.Enabled = False
9821         End If
9822     End Sub
9823
9824     Private Sub CopyUserIdStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CopyUserIdStripMenuItem.Click
9825         CopyUserId()
9826     End Sub
9827
9828     Private Sub CopyUserId()
9829         If _curPost Is Nothing Then Exit Sub
9830         Dim clstr As String = _curPost.ScreenName
9831         Try
9832             Clipboard.SetDataObject(clstr, False, 5, 100)
9833         Catch ex As Exception
9834             MessageBox.Show(ex.Message)
9835         End Try
9836     End Sub
9837
9838     Private Sub ShowRelatedStatusesMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ShowRelatedStatusesMenuItem.Click, ShowRelatedStatusesMenuItem2.Click
9839         Dim backToTab As TabClass = If(_curTab Is Nothing, _statuses.Tabs(ListTab.SelectedTab.Text), _statuses.Tabs(_curTab.Text))
9840         If Me.ExistCurrentPost AndAlso Not _curPost.IsDm Then
9841             'PublicSearchも除外した方がよい?
9842             If _statuses.GetTabByType(TabUsageType.Related) Is Nothing Then
9843                 Const TabName As String = "Related Tweets"
9844                 Dim tName As String = TabName
9845                 If Not Me.AddNewTab(tName, False, TabUsageType.Related) Then
9846                     For i As Integer = 2 To 100
9847                         tName = TabName + i.ToString()
9848                         If Me.AddNewTab(tName, False, TabUsageType.Related) Then
9849                             _statuses.AddTab(tName, TabUsageType.Related, Nothing)
9850                             Exit For
9851                         End If
9852                     Next
9853                 Else
9854                     _statuses.AddTab(tName, TabUsageType.Related, Nothing)
9855                 End If
9856                 _statuses.GetTabByName(tName).UnreadManage = False
9857                 _statuses.GetTabByName(tName).Notify = False
9858             End If
9859
9860             Dim tb As TabClass = _statuses.GetTabByType(TabUsageType.Related)
9861             tb.RelationTargetPost = _curPost
9862             Me.ClearTab(tb.TabName, False)
9863             For i As Integer = 0 To ListTab.TabPages.Count - 1
9864                 If tb.TabName = ListTab.TabPages(i).Text Then
9865                     ListTab.SelectedIndex = i
9866                     ListTabSelect(ListTab.TabPages(i))
9867                     Exit For
9868                 End If
9869             Next
9870
9871             GetTimeline(WORKERTYPE.Related, 1, 1, tb.TabName)
9872         End If
9873     End Sub
9874
9875     Private Sub CacheInfoMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CacheInfoMenuItem.Click
9876         Dim buf As New StringBuilder
9877         buf.AppendFormat("キャッシュメモリ容量         : {0}bytes({1}MB)" + vbCrLf, DirectCast(TIconDic, ImageDictionary).CacheMemoryLimit, DirectCast(TIconDic, ImageDictionary).CacheMemoryLimit / 1048576)
9878         buf.AppendFormat("物理メモリ使用割合           : {0}%" + vbCrLf, DirectCast(TIconDic, ImageDictionary).PhysicalMemoryLimit)
9879         buf.AppendFormat("キャッシュエントリ保持数     : {0}" + vbCrLf, DirectCast(TIconDic, ImageDictionary).CacheCount)
9880         buf.AppendFormat("キャッシュエントリ破棄数     : {0}" + vbCrLf, DirectCast(TIconDic, ImageDictionary).CacheRemoveCount)
9881         MessageBox.Show(buf.ToString, "アイコンキャッシュ使用状況")
9882     End Sub
9883
9884 #Region "Userstream"
9885     Private _isActiveUserstream As Boolean = False
9886
9887     Private Sub tw_PostDeleted(ByVal id As Long)
9888         Try
9889             If InvokeRequired AndAlso Not IsDisposed Then
9890                 Invoke(Sub()
9891                            _statuses.RemovePostReserve(id)
9892                            If _curTab IsNot Nothing AndAlso _statuses.Tabs(_curTab.Text).Contains(id) Then
9893                                _itemCache = Nothing
9894                                _itemCacheIndex = -1
9895                                _postCache = Nothing
9896                                DirectCast(_curTab.Tag, DetailsListView).Update()
9897                                If _curPost.StatusId = id Then DispSelectedPost(True)
9898                            End If
9899                        End Sub)
9900                 Exit Sub
9901             End If
9902         Catch ex As ObjectDisposedException
9903             Exit Sub
9904         End Try
9905     End Sub
9906
9907     Private Sub tw_NewPostFromStream()
9908         If SettingDialog.ReadOldPosts Then
9909             _statuses.SetRead() '新着時未読クリア
9910         End If
9911
9912         Dim rsltAddCount As Integer = _statuses.DistributePosts()
9913         SyncLock _syncObject
9914             Dim tm As Date = Now
9915             If _tlTimestamps.ContainsKey(tm) Then
9916                 _tlTimestamps(tm) += rsltAddCount
9917             Else
9918                 _tlTimestamps.Add(Now, rsltAddCount)
9919             End If
9920             Dim oneHour As Date = Now.Subtract(New TimeSpan(1, 0, 0))
9921             Dim keys As New List(Of Date)
9922             _tlCount = 0
9923             For Each key As Date In _tlTimestamps.Keys
9924                 If key.CompareTo(oneHour) < 0 Then
9925                     keys.Add(key)
9926                 Else
9927                     _tlCount += _tlTimestamps(key)
9928                 End If
9929             Next
9930             For Each key As Date In keys
9931                 _tlTimestamps.Remove(key)
9932             Next
9933             keys.Clear()
9934
9935             'Static before As DateTime = Now
9936             'If before.Subtract(Now).Seconds > -5 Then Exit Sub
9937             'before = Now
9938         End SyncLock
9939
9940         If SettingDialog.UserstreamPeriodInt > 0 Then Exit Sub
9941
9942         Try
9943             If InvokeRequired AndAlso Not IsDisposed Then
9944                 Invoke(New Action(Of Boolean)(AddressOf RefreshTimeline), True)
9945                 Exit Sub
9946             End If
9947         Catch ex As ObjectDisposedException
9948             Exit Sub
9949         End Try
9950     End Sub
9951
9952     Private Sub tw_UserStreamStarted()
9953         Me._isActiveUserstream = True
9954         If InvokeRequired AndAlso Not IsDisposed Then
9955             Invoke(New MethodInvoker(AddressOf tw_UserStreamStarted))
9956             Exit Sub
9957         End If
9958
9959         MenuItemUserStream.Text = "&UserStream ▶"
9960         MenuItemUserStream.Enabled = True
9961         StopToolStripMenuItem.Text = "&Stop"
9962         StopToolStripMenuItem.Enabled = True
9963
9964         StatusLabel.Text = "UserStream Started."
9965     End Sub
9966
9967     Private Sub tw_UserStreamStopped()
9968         Me._isActiveUserstream = False
9969         If InvokeRequired AndAlso Not IsDisposed Then
9970             Invoke(New MethodInvoker(AddressOf tw_UserStreamStopped))
9971             Exit Sub
9972         End If
9973
9974         MenuItemUserStream.Text = "&UserStream ■"
9975         MenuItemUserStream.Enabled = True
9976         StopToolStripMenuItem.Text = "&Start"
9977         StopToolStripMenuItem.Enabled = True
9978
9979         StatusLabel.Text = "UserStream Stopped."
9980     End Sub
9981
9982     Private Sub tw_UserStreamEventArrived(ByVal ev As Twitter.FormattedEvent)
9983         If InvokeRequired AndAlso Not IsDisposed Then
9984             Invoke(New Action(Of Twitter.FormattedEvent)(AddressOf tw_UserStreamEventArrived), ev)
9985             Exit Sub
9986         End If
9987         StatusLabel.Text = "Event: " + ev.Event
9988         'If ev.Event = "favorite" Then
9989         '    NotifyFavorite(ev)
9990         'End If
9991         NotifyEvent(ev)
9992         If ev.Event = "favorite" OrElse ev.Event = "unfavorite" Then
9993             If _curTab IsNot Nothing AndAlso _statuses.Tabs(_curTab.Text).Contains(ev.Id) Then
9994                 _itemCache = Nothing
9995                 _itemCacheIndex = -1
9996                 _postCache = Nothing
9997                 DirectCast(_curTab.Tag, DetailsListView).Update()
9998             End If
9999             If ev.Event = "unfavorite" AndAlso ev.Username.ToLower.Equals(tw.Username.ToLower) Then
10000                 RemovePostFromFavTab(New Int64() {ev.Id})
10001             End If
10002         End If
10003     End Sub
10004
10005     Private Sub NotifyEvent(ByVal ev As Twitter.FormattedEvent)
10006         '新着通知 
10007         If BalloonRequired(ev) Then
10008             NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning
10009             If SettingDialog.DispUsername Then NotifyIcon1.BalloonTipTitle = tw.Username + " - " Else NotifyIcon1.BalloonTipTitle = ""
10010             NotifyIcon1.BalloonTipTitle += "Tween [" + ev.Event.ToUpper() + "] by " + DirectCast(IIf(Not String.IsNullOrEmpty(ev.Username), ev.Username, ""), String)
10011             If Not String.IsNullOrEmpty(ev.Target) Then
10012                 NotifyIcon1.BalloonTipText = ev.Target
10013             Else
10014                 NotifyIcon1.BalloonTipText = " "
10015             End If
10016             NotifyIcon1.ShowBalloonTip(500)
10017         End If
10018
10019         'サウンド再生
10020         Dim snd As String = SettingDialog.EventSoundFile
10021         If Not _initial AndAlso SettingDialog.PlaySound AndAlso snd <> "" Then
10022             If CBool(ev.Eventtype And SettingDialog.EventNotifyFlag) AndAlso IsMyEventNotityAsEventType(ev) Then
10023                 Try
10024                     Dim dir As String = My.Application.Info.DirectoryPath
10025                     If Directory.Exists(Path.Combine(dir, "Sounds")) Then
10026                         dir = Path.Combine(dir, "Sounds")
10027                     End If
10028                     My.Computer.Audio.Play(Path.Combine(dir, snd), AudioPlayMode.Background)
10029                 Catch ex As Exception
10030
10031                 End Try
10032             End If
10033         End If
10034     End Sub
10035
10036     Private Sub StopToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StopToolStripMenuItem.Click
10037         MenuItemUserStream.Enabled = False
10038         If Me._isActiveUserstream Then
10039             tw.StopUserStream()
10040         Else
10041             tw.StartUserStream()
10042         End If
10043     End Sub
10044
10045     Private Sub TrackToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TrackToolStripMenuItem.Click
10046         Static inputTrack As String = ""
10047         If TrackToolStripMenuItem.Checked Then
10048             Using inputForm As New InputTabName
10049                 inputForm.TabName = inputTrack
10050                 inputForm.FormTitle = "Input track word"
10051                 inputForm.FormDescription = "Track word"
10052                 If inputForm.ShowDialog() <> Windows.Forms.DialogResult.OK Then
10053                     TrackToolStripMenuItem.Checked = False
10054                     Exit Sub
10055                 End If
10056                 inputTrack = inputForm.TabName.Trim()
10057             End Using
10058             If Not inputTrack.Equals(tw.TrackWord) Then
10059                 tw.TrackWord = inputTrack
10060                 Me._modifySettingCommon = True
10061                 TrackToolStripMenuItem.Checked = Not String.IsNullOrEmpty(inputTrack)
10062                 tw.ReconnectUserStream()
10063             End If
10064         Else
10065             tw.TrackWord = ""
10066             tw.ReconnectUserStream()
10067         End If
10068         Me._modifySettingCommon = True
10069     End Sub
10070
10071     Private Sub AllrepliesToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AllrepliesToolStripMenuItem.Click
10072         tw.AllAtReply = AllrepliesToolStripMenuItem.Checked
10073         Me._modifySettingCommon = True
10074         tw.ReconnectUserStream()
10075     End Sub
10076
10077     Private Sub EventViewerMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles EventViewerMenuItem.Click
10078         If evtDialog Is Nothing OrElse evtDialog.IsDisposed Then
10079             evtDialog = Nothing
10080             evtDialog = New EventViewerDialog
10081             evtDialog.Owner = Me
10082             '親の中央に表示
10083             Dim pos As Point = evtDialog.Location
10084             pos.X = Convert.ToInt32(Me.Location.X + Me.Size.Width / 2 - evtDialog.Size.Width / 2)
10085             pos.Y = Convert.ToInt32(Me.Location.Y + Me.Size.Height / 2 - evtDialog.Size.Height / 2)
10086             evtDialog.Location = pos
10087         End If
10088         evtDialog.EventSource = tw.StoredEvent
10089         If Not evtDialog.Visible Then
10090             evtDialog.Show(Me)
10091         Else
10092             evtDialog.Activate()
10093         End If
10094         Me.TopMost = Me.SettingDialog.AlwaysTop
10095     End Sub
10096 #End Region
10097
10098     Private Sub TweenRestartMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles TweenRestartMenuItem.Click
10099         _endingFlag = True
10100         Try
10101             Me.Close()
10102             Application.Restart()
10103         Catch ex As Exception
10104             MessageBox.Show("Failed to restart. Please run Tween manually.")
10105         End Try
10106     End Sub
10107
10108     Private Sub OpenOwnFavedMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles OpenOwnFavedMenuItem.Click
10109         If Not tw.Username = "" Then OpenUriAsync(My.Resources.FavstarUrl + "users/" + tw.Username + "/recent")
10110     End Sub
10111
10112     Private Sub OpenOwnHomeMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles OpenOwnHomeMenuItem.Click
10113         OpenUriAsync("http://twitter.com/" + tw.Username)
10114     End Sub
10115
10116     Private Sub doTranslation(ByVal str As String)
10117         Dim g As New Google
10118         Dim buf As String = ""
10119         If String.IsNullOrEmpty(str) Then Exit Sub
10120         Dim srclng As String = g.LanguageDetect(str)
10121         Dim dstlng As String = SettingDialog.TranslateLanguage
10122         Dim msg As String = ""
10123         If srclng <> dstlng AndAlso g.Translate(srclng, dstlng, str, buf, msg) Then
10124             PostBrowser.DocumentText = createDetailHtml(buf)
10125         Else
10126             If msg.StartsWith("Err:") Then
10127                 StatusLabel.Text = msg
10128             End If
10129         End If
10130     End Sub
10131
10132     Private Sub TranslationToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TranslationToolStripMenuItem.Click
10133         If Not Me.ExistCurrentPost Then Exit Sub
10134         doTranslation(_curPost.TextFromApi)
10135     End Sub
10136
10137     Private Sub SelectionTranslationToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectionTranslationToolStripMenuItem.Click
10138         doTranslation(WebBrowser_GetSelectionText(PostBrowser))
10139     End Sub
10140
10141     Private ReadOnly Property ExistCurrentPost As Boolean
10142         Get
10143             If _curPost Is Nothing Then Return False
10144             If _curPost.IsDeleted Then Return False
10145             Return True
10146         End Get
10147     End Property
10148
10149     Protected Overrides Sub Finalize()
10150         MyBase.Finalize()
10151     End Sub
10152
10153     Private Sub ShowUserTimelineToolStripMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ShowUserTimelineToolStripMenuItem.Click, ShowUserTimelineContextMenuItem.Click
10154         ShowUserTimeline()
10155     End Sub
10156
10157     Private Shared _instance As TweenMain
10158
10159     Public Shared Function GetInstance() As TweenMain
10160         Return _instance
10161     End Function
10162
10163     Public ReadOnly Property FavEventChangeUnread As Boolean
10164         Get
10165             Return SettingDialog.FavEventUnread
10166         End Get
10167     End Property
10168
10169     Private Function GetUserIdFromCurPostOrInput(ByVal caption As String) As String
10170         Dim id As String = ""
10171         If _curPost IsNot Nothing Then
10172             id = _curPost.ScreenName
10173         End If
10174         Using inputName As New InputTabName()
10175             inputName.FormTitle = caption
10176             inputName.FormDescription = My.Resources.FRMessage1
10177             inputName.TabName = id
10178             If inputName.ShowDialog() = Windows.Forms.DialogResult.OK AndAlso _
10179                Not String.IsNullOrEmpty(inputName.TabName.Trim()) Then
10180                 id = inputName.TabName.Trim
10181             Else
10182                 id = ""
10183             End If
10184         End Using
10185         Return id
10186     End Function
10187
10188     Private Sub UserTimelineToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UserTimelineToolStripMenuItem.Click
10189         Dim id As String = GetUserIdFromCurPostOrInput("Show UserTimeline")
10190         If Not String.IsNullOrEmpty(id) Then
10191             AddNewTabForUserTimeline(id)
10192         End If
10193     End Sub
10194
10195     Private Sub UserFavorareToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UserFavorareToolStripMenuItem.Click
10196         Dim id As String = GetUserIdFromCurPostOrInput("Show Favstar")
10197         If Not String.IsNullOrEmpty(id) Then
10198             OpenUriAsync(My.Resources.FavstarUrl + "users/" + id + "/recent")
10199         End If
10200     End Sub
10201
10202     Private Sub SystemEvents_PowerModeChanged(ByVal sender As Object, ByVal e As Microsoft.Win32.PowerModeChangedEventArgs)
10203         If e.Mode = Microsoft.Win32.PowerModes.Resume Then osResumed = True
10204     End Sub
10205
10206 End Class