OSDN Git Service

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