root/lang/vb2005/Tween/trunk/Tween/Tween.vb @ 34199

Revision 34199, 247.5 kB (checked in by kiri_feather, 5 years ago)

@先強調表示追加(デフォルト背景ピンク)

  • Property svn:mime-type set to text/plain
  • Property svn:eol-style set to native
Line 
1' Tween - Client of Twitter
2' Copyright (c) 2007-2009 kiri_feather (@kiri_feather) <kiri_feather@gmail.com>
3'           (c) 2008-2009 Moz (@syo68k) <http://iddy.jp/profile/moz/>
4'           (c) 2008-2009 takeshik (@takeshik) <http://www.takeshik.org/>
5' All rights reserved.
6'
7' This file is part of Tween.
8'
9' This program is free software; you can redistribute it and/or modify it
10' under the terms of the GNU General Public License as published by the Free
11' Software Foundation; either version 3 of the License, or (at your option)
12' any later version.
13'
14' This program is distributed in the hope that it will be useful, but
15' WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16' or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17' for more details.
18'
19' You should have received a copy of the GNU General Public License along
20' with this program. If not, see <http://www.gnu.org/licenses/>, or write to
21' the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
22' Boston, MA 02110-1301, USA.
23
24Imports System
25Imports System.Text
26Imports System.Text.RegularExpressions
27Imports Tween.TweenCustomControl
28Imports System.IO
29Imports System.Web
30Imports System.Reflection
31Imports System.ComponentModel
32Imports System.Xml.XPath
33Imports System.Diagnostics
34
35Public Class TweenMain
36    '各種設定
37    Private _username As String         'ユーザー名
38    Private _password As String         'パスワード(デクリプト済み)
39
40    Private _mySize As Size             '画面サイズ
41    Private _myLoc As Point             '画面位置
42    Private _mySpDis As Integer         '区切り位置
43    Private _mySpDis2 As Integer        '発言欄区切り位置
44    Private _iconSz As Integer            'アイコンサイズ(現在は16、24、48の3種類。将来直接数字指定可能とする 注:24x24の場合に26と指定しているのはMSゴシック系フォントのための仕様)
45    Private _iconCol As Boolean           '1列表示の時True(48サイズのとき)
46
47    '雑多なフラグ類
48    Private _initial As Boolean         'True:起動時処理中
49    'Private listViewItemSorter As ListViewItemComparer      'リストソート用カスタムクラス
50    Private _tabDrag As Boolean           'タブドラッグ中フラグ(DoDragDropを実行するかの判定用)
51    Private _rclickTabName As String      '右クリックしたタブの名前(Tabコントロール機能不足対応)
52    Private ReadOnly _syncObject As New Object()    'ロック用
53    Private Const detailHtmlFormat1 As String = "<html><head><style type=""text/css""><!-- p {font-family: """
54    Private Const detailHtmlFormat2 As String = """, sans-serif; font-size: "
55    Private Const detailHtmlFormat3 As String = "pt;} --></style></head><body style=""margin:0px""><p>"
56    Private Const detailHtmlFormat4 As String = "</p></body></html>"
57    Private detailHtmlFormat As String
58
59    '設定ファイル関連
60    Private _cfg As SettingToConfig '旧
61    Private _cfgLocal As SettingLocal
62    Private _cfgCommon As SettingCommon
63
64    'サブ画面インスタンス
65    Private SettingDialog As New Setting()       '設定画面インスタンス
66    Private TabDialog As New TabsDialog()        'タブ選択ダイアログインスタンス
67    Private SearchDialog As New SearchWord()     '検索画面インスタンス
68    'Private _tabs As New List(Of TabStructure)() '要素TabStructureクラスのジェネリックリストインスタンス(タブ情報用)
69    Private fDialog As New FilterDialog() 'フィルター編集画面
70    Private UrlDialog As New OpenURL()
71    Private dialogAsShieldicon As New DialogAsShieldIcon() ' シールドアイコン付きダイアログ
72
73    '表示フォント、色、アイコン
74    Private _fntUnread As Font            '未読用フォント
75    Private _clUnread As Color            '未読用文字色
76    Private _fntReaded As Font            '既読用フォント
77    Private _clReaded As Color            '既読用文字色
78    Private _clFav As Color               'Fav用文字色
79    Private _clOWL As Color               '片思い用文字色
80    Private _fntDetail As Font            '発言詳細部用フォント
81    Private _clSelf As Color              '自分の発言用背景色
82    Private _clAtSelf As Color            '自分宛返信用背景色
83    Private _clTarget As Color            '選択発言者の他の発言用背景色
84    Private _clAtTarget As Color          '選択発言中の返信先用背景色
85    Private _clAtFromTarget As Color      '選択発言者への返信発言用背景色
86    Private _clAtTo As Color              '選択発言の唯一@先
87    Private _clInputBackcolor As Color      '入力欄背景色
88    Private _clInputFont As Color           '入力欄文字色
89    Private _fntInputFont As Font           '入力欄フォント
90    'Private TIconList As ImageList        '発言詳細部用アイコン画像リスト
91    Private TIconDic As Dictionary(Of String, Image)        '発言詳細部用アイコン画像リスト
92    Private TIconSmallList As ImageList   'リスト表示用アイコン画像リスト
93    Private NIconAt As Icon               'At.ico             タスクトレイアイコン:通常時
94    Private NIconAtRed As Icon            'AtRed.ico          タスクトレイアイコン:通信エラー時
95    Private NIconAtSmoke As Icon          'AtSmoke.ico        タスクトレイアイコン:オフライン時
96    Private NIconRefresh(3) As Icon       'Refresh.ico        タスクトレイアイコン:更新中(アニメーション用に4種類を保持するリスト)
97    Private TabIcon As Icon               'Tab.ico            未読のあるタブ用アイコン
98    Private MainIcon As Icon              'Main.ico           画面左上のアイコン
99
100    Private _anchorPost As PostClass
101    Private _anchorFlag As Boolean        'True:関連発言移動中(関連移動以外のオペレーションをするとFalseへ。Trueだとリスト背景色をアンカー発言選択中として描画)
102
103    Private _history As New List(Of String)()   '発言履歴
104    Private _hisIdx As Integer                  '発言履歴カレントインデックス
105
106    Private Const _replyHtml As String = "@<a target=""_self"" href=""https://twitter.com/"
107
108    '発言投稿時のAPI引数(発言編集時に設定。手書きreplyでは設定されない)
109    Private _reply_to_id As Long     ' リプライ先のステータスID 0の場合はリプライではない 注:複数あてのものはリプライではない
110    Private _reply_to_name As String    ' リプライ先ステータスの書き込み者の名前
111
112    '時速表示用
113    Private _postTimestamps As New List(Of Date)()
114    Private _favTimestamps As New List(Of Date)()
115    Private _tlTimestamps As New Dictionary(Of Date, Integer)()
116    Private _tlCount As Integer
117
118    ' 以下DrawItem関連
119    Private _brsHighLight As New SolidBrush(Color.FromKnownColor(KnownColor.Highlight))
120    Private _brsHighLightText As New SolidBrush(Color.FromKnownColor(KnownColor.HighlightText))
121    Private _brsForeColorUnread As SolidBrush
122    Private _brsForeColorReaded As SolidBrush
123    Private _brsForeColorFav As SolidBrush
124    Private _brsForeColorOWL As SolidBrush
125    Private _brsBackColorMine As SolidBrush
126    Private _brsBackColorAt As SolidBrush
127    Private _brsBackColorYou As SolidBrush
128    Private _brsBackColorAtYou As SolidBrush
129    Private _brsBackColorAtFromTarget As SolidBrush
130    Private _brsBackColorAtTo As SolidBrush
131    Private _brsBackColorNone As SolidBrush
132    Private _brsDeactiveSelection As New SolidBrush(Color.FromKnownColor(KnownColor.ButtonFace))
133    Private sf As New StringFormat()
134    'Private _columnIdx As Integer   'ListviewのDisplayIndex退避用(DrawItemで使用)
135    'Private _columnChangeFlag As Boolean
136
137    '''''''''''''''''''''''''''''''''''''''''''''''''''''
138    Private _statuses As TabInformations
139    Private _itemCache() As ListViewItem
140    Private _itemCacheIndex As Integer
141    Private _postCache() As PostClass
142    Private _curTab As TabPage
143    Private _curItemIndex As Integer
144    Private _curList As DetailsListView
145    Private _curPost As PostClass
146    Private _waitFollower As Boolean = False
147    Private _waitTimeline As Boolean = False
148    Private _waitReply As Boolean = False
149    Private _waitDm As Boolean = False
150    Private _bw(9) As BackgroundWorker
151    Private cMode As Integer
152    Private StatusLabel As New ToolStripLabelHistory
153    Private shield As New ShieldIcon
154    Private SecurityManager As InternetSecurityManager
155    '''''''''''''''''''''''''''''''''''''''''''''''''''''
156
157#If DEBUG Then
158    Private _drawcount As Long = 0
159    Private _drawtime As Long = 0
160#End If
161
162    'URL短縮のUndo用
163    Private Structure urlUndo
164        Public Before As String
165        Public After As String
166    End Structure
167
168    Private urlUndoBuffer As Generic.List(Of urlUndo) = Nothing
169
170    Friend Class Win32Api
171        '画面をブリンクするためのWin32API。起動時に10ページ読み取りごとに継続確認メッセージを表示する際の通知強調用
172        Friend Declare Function FlashWindow Lib "user32.dll" ( _
173            ByVal hwnd As Integer, ByVal bInvert As Integer) As Integer
174    End Class
175
176    'Backgroundworkerの処理結果通知用引数構造体
177    Private Structure GetWorkerResult
178        Public retMsg As String                     '処理結果詳細メッセージ。エラー時に値がセットされる
179        'Public notifyPosts As List(Of PostClass) '取得した発言。Twitter.MyListItem構造体を要素としたジェネリックリスト
180        Public page As Integer                      '取得対象ページ番号
181        Public endPage As Integer                   '取得終了ページ番号(継続可能ならインクリメントされて返る。pageと比較して継続判定)
182        Public type As WORKERTYPE                   '処理種別
183        Public imgs As Dictionary(Of String, Image)                    '新規取得したアイコンイメージ
184        Public tName As String                      'Fav追加・削除時のタブ名
185        Public ids As List(Of Long)               'Fav追加・削除時のID
186        Public sIds As List(Of Long)                  'Fav追加・削除成功分のID
187        Public newDM As Boolean
188        'Public soundFile As String
189        Public addCount As Integer
190    End Structure
191
192    'Backgroundworkerへ処理内容を通知するための引数用構造体
193    Private Structure GetWorkerArg
194        Public page As Integer                      '処理対象ページ番号
195        Public endPage As Integer                   '処理終了ページ番号(起動時の読み込みページ数。通常時はpageと同じ値をセット)
196        Public type As WORKERTYPE                   '処理種別
197        Public status As String                     '発言POST時の発言内容
198        Public ids As List(Of Long)               'Fav追加・削除時のItemIndex
199        Public sIds As List(Of Long)              'Fav追加・削除成功分のItemIndex
200        Public tName As String                      'Fav追加・削除時のタブ名
201    End Structure
202
203    '検索処理タイプ
204    Private Enum SEARCHTYPE
205        DialogSearch
206        NextSearch
207        PrevSearch
208    End Enum
209
210    Private Sub TweenMain_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
211        '画面が他画面の裏に隠れると、アイコン画像が再描画されない問題の対応
212        If UserPicture.Image IsNot Nothing Then
213            UserPicture.Invalidate(False)
214        End If
215        '画面がアクティブになったら、発言欄の背景色戻す
216        If StatusText.Focused Then
217            Me.StatusText_Enter(Me.StatusText, System.EventArgs.Empty)
218        End If
219    End Sub
220
221    Private Sub TweenMain_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
222        '後始末
223        SettingDialog.Dispose()
224        TabDialog.Dispose()
225        SearchDialog.Dispose()
226        fDialog.Dispose()
227        UrlDialog.Dispose()
228        dialogAsShieldicon.Dispose()
229        If TIconDic IsNot Nothing AndAlso TIconDic.Keys.Count > 0 Then
230            For Each key As String In TIconDic.Keys
231                TIconDic(key).Dispose()
232            Next
233            TIconDic.Clear()
234        End If
235        If TIconSmallList IsNot Nothing Then TIconSmallList.Dispose()
236        If NIconAt IsNot Nothing Then NIconAt.Dispose()
237        If NIconAtRed IsNot Nothing Then NIconAtRed.Dispose()
238        If NIconAtSmoke IsNot Nothing Then NIconAtSmoke.Dispose()
239        If NIconRefresh(0) IsNot Nothing Then NIconRefresh(0).Dispose()
240        If NIconRefresh(1) IsNot Nothing Then NIconRefresh(1).Dispose()
241        If NIconRefresh(2) IsNot Nothing Then NIconRefresh(2).Dispose()
242        If NIconRefresh(3) IsNot Nothing Then NIconRefresh(3).Dispose()
243        If TabIcon IsNot Nothing Then TabIcon.Dispose()
244        If MainIcon IsNot Nothing Then MainIcon.Dispose()
245        _brsHighLight.Dispose()
246        _brsHighLightText.Dispose()
247        If _brsForeColorUnread IsNot Nothing Then _brsForeColorUnread.Dispose()
248        If _brsForeColorReaded IsNot Nothing Then _brsForeColorReaded.Dispose()
249        If _brsForeColorFav IsNot Nothing Then _brsForeColorFav.Dispose()
250        If _brsForeColorOWL IsNot Nothing Then _brsForeColorOWL.Dispose()
251        If _brsBackColorMine IsNot Nothing Then _brsBackColorMine.Dispose()
252        If _brsBackColorAt IsNot Nothing Then _brsBackColorAt.Dispose()
253        If _brsBackColorYou IsNot Nothing Then _brsBackColorYou.Dispose()
254        If _brsBackColorAtYou IsNot Nothing Then _brsBackColorAtYou.Dispose()
255        If _brsBackColorAtFromTarget IsNot Nothing Then _brsBackColorAtFromTarget.Dispose()
256        If _brsBackColorAtTo IsNot Nothing Then _brsBackColorAtTo.Dispose()
257        If _brsBackColorNone IsNot Nothing Then _brsBackColorNone.Dispose()
258        If _brsDeactiveSelection IsNot Nothing Then _brsDeactiveSelection.Dispose()
259        shield.Dispose()
260        StatusLabel.Dispose()
261        sf.Dispose()
262    End Sub
263
264    Private Sub LoadIcons()
265        '着せ替えアイコン対応
266        'タスクトレイ通常時アイコン
267        Dim dir As String = Application.StartupPath
268
269        Try
270            NIconAt = New Icon(Path.Combine(dir, "Icons\At.ico"))
271        Catch ex As Exception
272            NIconAt = My.Resources.At
273        End Try
274        'タスクトレイエラー時アイコン
275        Try
276            NIconAtRed = New Icon(Path.Combine(dir, "Icons\AtRed.ico"))
277        Catch ex As Exception
278            NIconAtRed = My.Resources.AtRed
279        End Try
280        'タスクトレイオフライン時アイコン
281        Try
282            NIconAtSmoke = New Icon(Path.Combine(dir, "Icons\AtSmoke.ico"))
283        Catch ex As Exception
284            NIconAtSmoke = My.Resources.AtSmoke
285        End Try
286        'タスクトレイ更新中アイコン
287        'アニメーション対応により4種類読み込み
288        Try
289            NIconRefresh(0) = New Icon(Path.Combine(dir, "Icons\Refresh.ico"))
290        Catch ex As Exception
291            NIconRefresh(0) = My.Resources.Refresh
292        End Try
293        Try
294            NIconRefresh(1) = New Icon(Path.Combine(dir, "Icons\Refresh2.ico"))
295        Catch ex As Exception
296            NIconRefresh(1) = My.Resources.Refresh2
297        End Try
298        Try
299            NIconRefresh(2) = New Icon(Path.Combine(dir, "Icons\Refresh3.ico"))
300        Catch ex As Exception
301            NIconRefresh(2) = My.Resources.Refresh3
302        End Try
303        Try
304            NIconRefresh(3) = New Icon(Path.Combine(dir, "Icons\Refresh4.ico"))
305        Catch ex As Exception
306            NIconRefresh(3) = My.Resources.Refresh4
307        End Try
308        'タブ見出し未読表示アイコン
309        Try
310            TabIcon = New Icon(Path.Combine(dir, "Icons\Tab.ico"))
311        Catch ex As Exception
312            TabIcon = My.Resources.TabIcon
313        End Try
314        '画面のアイコン
315        Try
316            MainIcon = New Icon(Path.Combine(dir, "Icons\MIcon.ico"))
317        Catch ex As Exception
318            MainIcon = My.Resources.MIcon
319        End Try
320
321    End Sub
322
323    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
324        Me.Visible = False
325        SecurityManager = New InternetSecurityManager(PostBrowser)
326
327        VerUpMenuItem.Image = shield.Icon
328        If Not My.Application.CommandLineArgs.Count = 0 AndAlso My.Application.CommandLineArgs.Contains("/d") Then TraceFlag = True
329        Me.StatusStrip1.Items.Add(StatusLabel)
330
331        LoadIcons() ' アイコン読み込み
332
333        '発言保持クラス
334        _statuses = TabInformations.GetInstance()
335
336        'アイコン設定
337        Me.Icon = MainIcon              'メインフォーム(TweenMain)
338        NotifyIcon1.Icon = NIconAt      'タスクトレイ
339        TabImage.Images.Add(TabIcon)    'タブ見出し
340
341        ContextMenuStrip1.OwnerItem = Nothing
342        ContextMenuStrip2.OwnerItem = Nothing
343        ContextMenuTabProperty.OwnerItem = Nothing
344
345        SettingDialog.Owner = Me
346        SearchDialog.Owner = Me
347        fDialog.Owner = Me
348        TabDialog.Owner = Me
349        UrlDialog.Owner = Me
350
351        _history.Add("")
352        _hisIdx = 0
353        _reply_to_id = 0
354        _reply_to_name = Nothing
355
356        '_columnChangeFlag = True
357
358        '<<<<<<<<<設定関連>>>>>>>>>
359        '設定コンバージョン
360        ConvertConfig()
361
362        ''設定読み出し
363        'ユーザー名とパスワードの取得
364        _username = _cfgCommon.UserName
365        _password = _cfgCommon.Password
366        '新着バルーン通知のチェック状態設定
367        NewPostPopMenuItem.Checked = _cfgCommon.NewAllPop
368
369        'フォント&文字色&背景色保持
370        _fntUnread = _cfgLocal.FontUnread
371        _clUnread = _cfgLocal.ColorUnread
372        _fntReaded = _cfgLocal.FontRead
373        _clReaded = _cfgLocal.ColorRead
374        _clFav = _cfgLocal.ColorFav
375        _clOWL = _cfgLocal.ColorOWL
376        _fntDetail = _cfgLocal.FontDetail
377        _clSelf = _cfgLocal.ColorSelf
378        _clAtSelf = _cfgLocal.ColorAtSelf
379        _clTarget = _cfgLocal.ColorTarget
380        _clAtTarget = _cfgLocal.ColorAtTarget
381        _clAtFromTarget = _cfgLocal.ColorAtFromTarget
382        _clAtTo = _cfgLocal.ColorAtTo
383        _clInputBackcolor = _cfgLocal.ColorInputBackcolor
384        _clInputFont = _cfgLocal.ColorInputFont
385        _fntInputFont = _cfgLocal.FontInputFont
386
387        _brsForeColorUnread = New SolidBrush(_clUnread)
388        _brsForeColorReaded = New SolidBrush(_clReaded)
389        _brsForeColorFav = New SolidBrush(_clFav)
390        _brsForeColorOWL = New SolidBrush(_clOWL)
391        _brsBackColorMine = New SolidBrush(_clSelf)
392        _brsBackColorAt = New SolidBrush(_clAtSelf)
393        _brsBackColorYou = New SolidBrush(_clTarget)
394        _brsBackColorAtYou = New SolidBrush(_clAtTarget)
395        _brsBackColorAtFromTarget = New SolidBrush(_clAtFromTarget)
396        _brsBackColorAtTo = New SolidBrush(_clAtTo)
397        _brsBackColorNone = New SolidBrush(Color.FromKnownColor(KnownColor.Window))
398        detailHtmlFormat = detailHtmlFormat1 + _fntDetail.Name + detailHtmlFormat2 + _fntDetail.Size.ToString() + detailHtmlFormat3
399
400        ' StringFormatオブジェクトへの事前設定
401        sf.Alignment = StringAlignment.Near
402        sf.LineAlignment = StringAlignment.Near
403
404        '設定画面への反映
405        SettingDialog.UserID = _username                                'ユーザ名
406        SettingDialog.PasswordStr = _password                           'パスワード
407        SettingDialog.TimelinePeriodInt = _cfgCommon.TimelinePeriod
408        SettingDialog.ReplyPeriodInt = _cfgCommon.ReplyPeriod
409        SettingDialog.DMPeriodInt = _cfgCommon.DMPeriod
410        SettingDialog.NextPageThreshold = _cfgCommon.NextPageThreshold
411        SettingDialog.NextPagesInt = _cfgCommon.NextPages
412        SettingDialog.MaxPostNum = _cfgCommon.MaxPostNum
413
414        '起動時読み込みページ数
415        SettingDialog.ReadPages = _cfgCommon.ReadPages
416        SettingDialog.ReadPagesReply = _cfgCommon.ReadPagesReply
417        SettingDialog.ReadPagesDM = _cfgCommon.ReadPagesDM
418
419        '起動時読み込み分を既読にするか。Trueなら既読として処理
420        SettingDialog.Readed = _cfgCommon.Read
421        '新着取得時のリストスクロールをするか。Trueならスクロールしない
422        ListLockMenuItem.Checked = _cfgCommon.ListLock
423        SettingDialog.IconSz = _cfgCommon.IconSize
424        '文末ステータス
425        SettingDialog.Status = _cfgLocal.StatusText
426        '未読管理。Trueなら未読管理する
427        SettingDialog.UnreadManage = _cfgCommon.UnreadManage
428        'サウンド再生(タブ別設定より優先)
429        SettingDialog.PlaySound = _cfgCommon.PlaySound
430        PlaySoundMenuItem.Checked = SettingDialog.PlaySound
431        '片思い表示。Trueなら片思い表示する
432        SettingDialog.OneWayLove = _cfgCommon.OneWayLove
433        'フォント&文字色&背景色
434        SettingDialog.FontUnread = _fntUnread
435        SettingDialog.ColorUnread = _clUnread
436        SettingDialog.FontReaded = _fntReaded
437        SettingDialog.ColorReaded = _clReaded
438        SettingDialog.ColorFav = _clFav
439        SettingDialog.ColorOWL = _clOWL
440        SettingDialog.FontDetail = _fntDetail
441        SettingDialog.ColorSelf = _clSelf
442        SettingDialog.ColorAtSelf = _clAtSelf
443        SettingDialog.ColorTarget = _clTarget
444        SettingDialog.ColorAtTarget = _clAtTarget
445        SettingDialog.ColorAtFromTarget = _clAtFromTarget
446        SettingDialog.ColorAtTo = _clAtTo
447        SettingDialog.ColorInputBackcolor = _clInputBackcolor
448        SettingDialog.ColorInputFont = _clInputFont
449        SettingDialog.FontInputFont = _fntInputFont
450
451        SettingDialog.NameBalloon = _cfgCommon.NameBalloon
452        SettingDialog.PostCtrlEnter = _cfgCommon.PostCtrlEnter
453        SettingDialog.UseAPI = _cfgCommon.UseApi
454        SettingDialog.CountApi = _cfgCommon.CountApi
455        SettingDialog.UsePostMethod = False
456        SettingDialog.HubServer = _cfgCommon.HubServer
457        SettingDialog.BrowserPath = _cfgLocal.BrowserPath
458        SettingDialog.CheckReply = _cfgCommon.CheckReply
459        SettingDialog.PostAndGet = _cfgCommon.PostAndGet
460        SettingDialog.UseRecommendStatus = _cfgLocal.UseRecommendStatus
461        SettingDialog.DispUsername = _cfgCommon.DispUsername
462        SettingDialog.CloseToExit = _cfgCommon.CloseToExit
463        SettingDialog.MinimizeToTray = _cfgCommon.MinimizeToTray
464        SettingDialog.DispLatestPost = _cfgCommon.DispLatestPost
465        SettingDialog.SortOrderLock = _cfgCommon.SortOrderLock
466        SettingDialog.TinyUrlResolve = _cfgCommon.TinyUrlResolve
467
468        SettingDialog.ProxyType = _cfgLocal.ProxyType
469        SettingDialog.ProxyAddress = _cfgLocal.ProxyAddress
470        SettingDialog.ProxyPort = _cfgLocal.ProxyPort
471        SettingDialog.ProxyUser = _cfgLocal.ProxyUser
472        SettingDialog.ProxyPassword = _cfgLocal.ProxyPassword
473
474        SettingDialog.PeriodAdjust = _cfgCommon.PeriodAdjust
475        SettingDialog.StartupVersion = _cfgCommon.StartupVersion
476        SettingDialog.StartupKey = _cfgCommon.StartupKey
477        SettingDialog.StartupFollowers = _cfgCommon.StartupFollowers
478        SettingDialog.StartupAPImodeNoWarning = _cfgCommon.StartupApiModeNoWarning
479        SettingDialog.RestrictFavCheck = _cfgCommon.RestrictFavCheck
480        SettingDialog.AlwaysTop = _cfgCommon.AlwaysTop
481        SettingDialog.UrlConvertAuto = _cfgCommon.UrlConvertAuto
482
483        SettingDialog.OutputzEnabled = _cfgCommon.Outputz
484        SettingDialog.OutputzKey = _cfgCommon.OutputzKey
485        SettingDialog.OutputzUrlmode = _cfgCommon.OutputzUrlMode
486
487        SettingDialog.UseUnreadStyle = _cfgCommon.UseUnreadStyle
488        SettingDialog.DefaultTimeOut = _cfgCommon.DefaultTimeOut
489        SettingDialog.ProtectNotInclude = _cfgCommon.ProtectNotInclude
490        SettingDialog.PlaySound = _cfgCommon.PlaySound
491        SettingDialog.DateTimeFormat = _cfgCommon.DateTimeFormat
492        SettingDialog.LimitBalloon = _cfgCommon.LimitBalloon
493        SettingDialog.AutoShortUrlFirst = _cfgCommon.AutoShortUrlFirst
494
495        '書式指定文字列エラーチェック
496        Try
497            If DateTime.Now.ToString(SettingDialog.DateTimeFormat).Length = 0 Then
498                ' このブロックは絶対に実行されないはず
499                ' 変換が成功した場合にLengthが0にならない
500                SettingDialog.DateTimeFormat = "yyyy/MM/dd H:mm:ss"
501            End If
502        Catch ex As FormatException
503            ' FormatExceptionが発生したら初期値を設定 (=yyyy/MM/dd H:mm:ssとみなされる)
504            SettingDialog.DateTimeFormat = "yyyy/MM/dd H:mm:ss"
505        End Try
506
507        Outputz.key = SettingDialog.OutputzKey
508        Outputz.Enabled = SettingDialog.OutputzEnabled
509        Select Case SettingDialog.OutputzUrlmode
510            Case OutputzUrlmode.twittercom
511                Outputz.url = "http://twitter.com/"
512            Case OutputzUrlmode.twittercomWithUsername
513                Outputz.url = "http://twitter.com/" + SettingDialog.UserID
514        End Select
515
516        _initial = True
517
518        'ユーザー名、パスワードが未設定なら設定画面を表示(初回起動時など)
519        If _username = "" Or _password = "" Then
520            '設定せずにキャンセルされた場合はプログラム終了
521            If SettingDialog.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
522                Application.Exit()  '強制終了
523                Exit Sub
524            End If
525            _username = SettingDialog.UserID
526            _password = SettingDialog.PasswordStr
527            '設定されたが、依然ユーザー名とパスワードが未設定ならプログラム終了
528            If _username = "" Or _password = "" Then
529                Application.Exit()  '強制終了
530                Exit Sub
531            End If
532            '新しい設定を反映
533            'フォント&文字色&背景色保持
534            _fntUnread = SettingDialog.FontUnread
535            _clUnread = SettingDialog.ColorUnread
536            _fntReaded = SettingDialog.FontReaded
537            _clReaded = SettingDialog.ColorReaded
538            _clFav = SettingDialog.ColorFav
539            _clOWL = SettingDialog.ColorOWL
540            _fntDetail = SettingDialog.FontDetail
541            _clSelf = SettingDialog.ColorSelf
542            _clAtSelf = SettingDialog.ColorAtSelf
543            _clTarget = SettingDialog.ColorTarget
544            _clAtTarget = SettingDialog.ColorAtTarget
545            _clAtFromTarget = SettingDialog.ColorAtFromTarget
546            _clAtTo = SettingDialog.ColorAtTo
547            _clInputBackcolor = SettingDialog.ColorInputBackcolor
548            _clInputFont = SettingDialog.ColorInputFont
549            _fntInputFont = SettingDialog.FontInputFont
550            _brsForeColorUnread.Dispose()
551            _brsForeColorReaded.Dispose()
552            _brsForeColorFav.Dispose()
553            _brsForeColorOWL.Dispose()
554            _brsForeColorUnread = New SolidBrush(_clUnread)
555            _brsForeColorReaded = New SolidBrush(_clReaded)
556            _brsForeColorFav = New SolidBrush(_clFav)
557            _brsForeColorOWL = New SolidBrush(_clOWL)
558            _brsBackColorMine.Dispose()
559            _brsBackColorAt.Dispose()
560            _brsBackColorYou.Dispose()
561            _brsBackColorAtYou.Dispose()
562            _brsBackColorAtFromTarget.Dispose()
563            _brsBackColorAtTo.Dispose()
564            _brsBackColorMine = New SolidBrush(_clSelf)
565            _brsBackColorAt = New SolidBrush(_clAtSelf)
566            _brsBackColorYou = New SolidBrush(_clTarget)
567            _brsBackColorAtYou = New SolidBrush(_clAtTarget)
568            _brsBackColorAtFromTarget = New SolidBrush(_clAtFromTarget)
569            _brsBackColorAtTo = New SolidBrush(_clAtTo)
570            detailHtmlFormat = detailHtmlFormat1 + _fntDetail.Name + detailHtmlFormat2 + _fntDetail.Size.ToString() + detailHtmlFormat3
571            '他の設定項目は、随時設定画面で保持している値を読み出して使用
572        End If
573
574        'Twitter用通信クラス初期化
575        Twitter.Username = _username
576        Twitter.Password = _password
577        Twitter.ProxyType = SettingDialog.ProxyType
578        Twitter.ProxyAddress = SettingDialog.ProxyAddress
579        Twitter.ProxyPort = SettingDialog.ProxyPort
580        Twitter.ProxyUser = SettingDialog.ProxyUser
581        Twitter.ProxyPassword = SettingDialog.ProxyPassword
582        Twitter.NextThreshold = SettingDialog.NextPageThreshold   '次頁取得閾値
583        Twitter.NextPages = SettingDialog.NextPagesInt    '閾値オーバー時の読み込みページ数(未使用)
584        Twitter.DefaultTimeOut = SettingDialog.DefaultTimeOut
585        Twitter.CountApi = SettingDialog.CountApi
586        Twitter.UseAPI = SettingDialog.UseAPI
587        Twitter.UsePostMethod = False
588        Twitter.HubServer = SettingDialog.HubServer
589        Twitter.RestrictFavCheck = SettingDialog.RestrictFavCheck
590        If IsNetworkAvailable() Then
591            If SettingDialog.StartupFollowers Then
592                _waitFollower = True
593                GetTimeline(WORKERTYPE.Follower, 0, 0)
594            End If
595        End If
596
597        'ウィンドウ設定
598        Me.ClientSize = _cfgLocal.FormSize
599        _mySize = Me.ClientSize                     'サイズ保持(最小化・最大化されたまま終了した場合の対応用)
600        Me.DesktopLocation = _cfgLocal.FormLocation
601        _myLoc = Me.DesktopLocation                        '位置保持(最小化・最大化されたまま終了した場合の対応用)
602        Me.TopMost = SettingDialog.AlwaysTop
603        _mySpDis = _cfgLocal.SplitterDistance
604        _mySpDis2 = _cfgLocal.StatusTextHeight
605        MultiLineMenuItem.Checked = _cfgLocal.StatusMultiline
606        Me.Tween_ClientSizeChanged(Me, Nothing)
607        PlaySoundMenuItem.Checked = SettingDialog.PlaySound
608        '入力欄
609        StatusText.Font = _fntInputFont
610        StatusText.ForeColor = _clInputFont
611
612        '全新着通知のチェック状態により、Reply&DMの新着通知有効無効切り替え(タブ別設定にするため削除予定)
613        If SettingDialog.UnreadManage = False Then
614            ReadedStripMenuItem.Enabled = False
615            UnreadStripMenuItem.Enabled = False
616        End If
617
618        'タイマー設定
619        'Recent取得間隔
620        If SettingDialog.TimelinePeriodInt > 0 Then
621            TimerTimeline.Interval = SettingDialog.TimelinePeriodInt * 1000
622        Else
623            TimerTimeline.Interval = 600000
624        End If
625        'Reply取得間隔
626        If SettingDialog.ReplyPeriodInt > 0 Then
627            TimerReply.Interval = SettingDialog.ReplyPeriodInt * 1000
628        Else
629            TimerReply.Interval = 6000000
630        End If
631        'DM取得間隔
632        If SettingDialog.DMPeriodInt > 0 Then
633            TimerDM.Interval = SettingDialog.DMPeriodInt * 1000
634        Else
635            TimerDM.Interval = 6000000
636        End If
637        '更新中アイコンアニメーション間隔
638        TimerRefreshIcon.Interval = 85
639
640        '状態表示部の初期化(画面右下)
641        StatusLabel.Text = ""
642        '文字カウンタ初期化
643        lblLen.Text = "140"
644
645        If SettingDialog.StartupKey Then
646            Twitter.GetWedata()
647        End If
648
649        ''''''''''''''''''''''''''''''''''''''''
650        _statuses.SortOrder = DirectCast(_cfgCommon.SortOrder, System.Windows.Forms.SortOrder)
651        Dim mode As IdComparerClass.ComparerMode
652        Select Case _cfgCommon.SortColumn
653            Case 0, 5, 6    '0:アイコン,5:未読マーク,6:プロテクト・フィルターマーク
654                'ソートしない
655                mode = IdComparerClass.ComparerMode.Id  'Idソートに読み替え
656            Case 1  'ニックネーム
657                mode = IdComparerClass.ComparerMode.Nickname
658            Case 2  '本文
659                mode = IdComparerClass.ComparerMode.Data
660            Case 3  '時刻=発言Id
661                mode = IdComparerClass.ComparerMode.Id
662            Case 4  '名前
663                mode = IdComparerClass.ComparerMode.Name
664            Case 7  'Source
665                mode = IdComparerClass.ComparerMode.Source
666        End Select
667        _statuses.SortMode = mode
668        ''''''''''''''''''''''''''''''''''''''''
669
670        Select Case SettingDialog.IconSz
671            Case IconSizes.IconNone
672                _iconSz = 0
673            Case IconSizes.Icon16
674                _iconSz = 16
675            Case IconSizes.Icon24
676                _iconSz = 26
677            Case IconSizes.Icon48
678                _iconSz = 48
679            Case IconSizes.Icon48_2
680                _iconSz = 48
681                _iconCol = True
682        End Select
683        If _iconSz = 0 Then
684            Twitter.GetIcon = False
685        Else
686            Twitter.GetIcon = True
687            Twitter.IconSize = _iconSz
688        End If
689        Twitter.TinyUrlResolve = SettingDialog.TinyUrlResolve
690
691        '発言詳細部アイコンをリストアイコンにサイズ変更
692        Dim sz As Integer = _iconSz
693        If _iconSz = 0 Then
694            sz = 16
695        End If
696        TIconSmallList = New ImageList
697        TIconSmallList.ImageSize = New Size(sz, sz)
698        TIconSmallList.ColorDepth = ColorDepth.Depth32Bit
699        '発言詳細部のアイコンリスト作成
700        TIconDic = New Dictionary(Of String, Image)
701
702        Twitter.ListIcon = TIconSmallList
703        Twitter.DetailIcon = TIconDic
704
705        StatusLabel.Text = My.Resources.Form1_LoadText1       '画面右下の状態表示を変更
706        StatusLabelUrl.Text = ""            '画面左下のリンク先URL表示部を初期化
707        PostBrowser.DocumentText = ""       '発言詳細部初期化
708        NameLabel.Text = ""                 '発言詳細部名前ラベル初期化
709        DateTimeLabel.Text = ""             '発言詳細部日時ラベル初期化
710
711        '<<<<<<<<タブ関連>>>>>>>
712        'デフォルトタブの存在チェック、ない場合には追加
713        If Not _statuses.Tabs.ContainsKey(DEFAULTTAB.RECENT) Then _statuses.Tabs.Add(DEFAULTTAB.RECENT, New TabClass(DEFAULTTAB.RECENT))
714        If Not _statuses.Tabs.ContainsKey(DEFAULTTAB.REPLY) Then _statuses.Tabs.Add(DEFAULTTAB.REPLY, New TabClass(DEFAULTTAB.REPLY))
715        If Not _statuses.Tabs.ContainsKey(DEFAULTTAB.DM) Then _statuses.Tabs.Add(DEFAULTTAB.DM, New TabClass(DEFAULTTAB.DM))
716        If Not _statuses.Tabs.ContainsKey(DEFAULTTAB.FAV) Then _statuses.Tabs.Add(DEFAULTTAB.FAV, New TabClass(DEFAULTTAB.FAV))
717        For Each tn As String In _statuses.Tabs.Keys
718            If Not AddNewTab(tn, True) Then Throw New Exception("タブ作成エラー")
719        Next
720
721        JumpUnreadMenuItem.ShortcutKeyDisplayString = "Space"
722        CopySTOTMenuItem.ShortcutKeyDisplayString = "Ctrl+C"
723        CopyURLMenuItem.ShortcutKeyDisplayString = "Ctrl+Shift+C"
724
725        AddHandler My.Computer.Network.NetworkAvailabilityChanged, AddressOf Network_NetworkAvailabilityChanged
726        If SettingDialog.MinimizeToTray = False OrElse Me.WindowState <> FormWindowState.Minimized Then
727            Me.Visible = True
728        End If
729        _curTab = ListTab.SelectedTab
730        _curItemIndex = -1
731        _curList = DirectCast(_curTab.Controls(0), DetailsListView)
732        SetMainWindowTitle()
733        SetNotifyIconText()
734
735        TimerColorize.Interval = 200
736        TimerColorize.Start()
737    End Sub
738
739    Private Function LoadConfig() As Boolean
740        _cfgCommon = SettingCommon.Load()
741        _cfgLocal = SettingLocal.Load()
742        If _cfgCommon.TabList.Count > 0 Then
743            For Each tabName As String In _cfgCommon.TabList
744                _statuses.Tabs.Add(tabName, SettingTab.Load(tabName).Tab)
745            Next
746        Else
747            _statuses.Tabs.Add(DEFAULTTAB.RECENT, New TabClass(DEFAULTTAB.RECENT))
748            _statuses.Tabs.Add(DEFAULTTAB.REPLY, New TabClass(DEFAULTTAB.REPLY))
749            _statuses.Tabs.Add(DEFAULTTAB.DM, New TabClass(DEFAULTTAB.DM))
750            _statuses.Tabs.Add(DEFAULTTAB.FAV, New TabClass(DEFAULTTAB.FAV))
751        End If
752        If System.IO.File.Exists(SettingCommon.GetSettingFilePath("")) Then
753            Return True
754        Else
755            Return False
756        End If
757    End Function
758
759    Private Sub ConvertConfig()
760        If LoadConfig() Then Exit Sub
761
762        _cfg = SettingToConfig.Load()
763        If _cfg Is Nothing Then Exit Sub
764
765        '新設定ファイルへ変換
766        '新しくエントリを増設する場合はここに書く必要はない
767        _cfgCommon.AlwaysTop = _cfg.AlwaysTop
768        _cfgCommon.AutoShortUrlFirst = _cfg.AutoShortUrlFirst
769        _cfgLocal.BrowserPath = _cfg.BrowserPath
770        _cfgCommon.CheckReply = _cfg.CheckReply
771        _cfgCommon.CloseToExit = _cfg.CloseToExit
772        _cfgLocal.ColorAtFromTarget = _cfg.ColorAtFromTarget
773        _cfgLocal.ColorAtSelf = _cfg.ColorAtSelf
774        _cfgLocal.ColorAtTarget = _cfg.ColorAtTarget
775        _cfgLocal.ColorFav = _cfg.ColorFav
776        _cfgLocal.ColorOWL = _cfg.ColorOWL
777        _cfgLocal.ColorRead = _cfg.ColorRead
778        _cfgLocal.ColorSelf = _cfg.ColorSelf
779        _cfgLocal.ColorTarget = _cfg.ColorTarget
780        _cfgLocal.ColorUnread = _cfg.ColorUnread
781        _cfgLocal.ColorInputBackcolor = _cfg.ColorInputBackcolor
782        _cfgLocal.ColorInputFont = _cfg.ColorInputFont
783        _cfgCommon.CountApi = _cfg.CountApi
784        _cfgCommon.CultureCode = _cfg.cultureCode
785        _cfgCommon.DateTimeFormat = _cfg.DateTimeFormat
786        _cfgCommon.DefaultTimeOut = _cfg.DefaultTimeOut
787        _cfgCommon.DispLatestPost = _cfg.DispLatestPost
788        _cfgLocal.DisplayIndex1 = _cfg.DisplayIndex1
789        _cfgLocal.DisplayIndex2 = _cfg.DisplayIndex2
790        _cfgLocal.DisplayIndex3 = _cfg.DisplayIndex3
791        _cfgLocal.DisplayIndex4 = _cfg.DisplayIndex4
792        _cfgLocal.DisplayIndex5 = _cfg.DisplayIndex5
793        _cfgLocal.DisplayIndex6 = _cfg.DisplayIndex6
794        _cfgLocal.DisplayIndex7 = _cfg.DisplayIndex7
795        _cfgLocal.DisplayIndex8 = _cfg.DisplayIndex8
796        _cfgCommon.DispUsername = _cfg.DispUsername
797        _cfgCommon.DMPeriod = _cfg.DMPeriod
798        _cfgLocal.FontDetail = _cfg.FontDetail
799        _cfgLocal.FontRead = _cfg.FontRead
800        _cfgLocal.FontUnread = _cfg.FontUnread
801        _cfgLocal.FontInputFont = _cfg.FontInputFont
802        _cfgLocal.FormLocation = _cfg.FormLocation
803        _cfgLocal.FormSize = _cfg.FormSize
804        _cfgCommon.HubServer = _cfg.HubServer
805        _cfgCommon.IconSize = _cfg.IconSize
806        _cfgCommon.LimitBalloon = _cfg.LimitBalloon
807        _cfgCommon.ListLock = _cfg.ListLock
808        _cfgCommon.MaxPostNum = _cfg.MaxPostNum
809        _cfgCommon.MinimizeToTray = _cfg.MinimizeToTray
810        _cfgCommon.NameBalloon = _cfg.NameBalloon
811        _cfgCommon.NewAllPop = _cfg.NewAllPop
812        _cfgCommon.NextPages = _cfg.NextPages
813        _cfgCommon.NextPageThreshold = _cfg.NextPageThreshold
814        _cfgCommon.OneWayLove = _cfg.OneWayLove
815        _cfgCommon.Outputz = _cfg.Outputz
816        _cfgCommon.OutputzKey = _cfg.OutputzKey
817        _cfgCommon.OutputzUrlMode = _cfg.OutputzUrlmode
818        _cfgCommon.Password = _cfg.Password
819        _cfgCommon.PeriodAdjust = _cfg.PeriodAdjust
820        _cfgCommon.PlaySound = _cfg.PlaySound
821        _cfgCommon.PostAndGet = _cfg.PostAndGet
822        _cfgCommon.PostCtrlEnter = _cfg.PostCtrlEnter
823        _cfgCommon.ProtectNotInclude = _cfg.ProtectNotInclude
824        _cfgLocal.ProxyAddress = _cfg.ProxyAddress
825        _cfgLocal.ProxyPassword = _cfg.ProxyPassword
826        _cfgLocal.ProxyPort = _cfg.ProxyPort
827        _cfgLocal.ProxyType = _cfg.ProxyType
828        _cfgLocal.ProxyUser = _cfg.ProxyUser
829        _cfgCommon.Read = _cfg.Read
830        _cfgCommon.ReadPages = _cfg.ReadPages
831        _cfgCommon.ReadPagesDM = _cfg.ReadPagesDM
832        _cfgCommon.ReadPagesReply = _cfg.ReadPagesReply
833        _cfgCommon.RestrictFavCheck = _cfg.RestrictFavCheck
834        _cfgCommon.SortColumn = _cfg.SortColumn
835        _cfgCommon.SortOrder = _cfg.SortOrder
836        _cfgCommon.SortOrderLock = _cfg.SortOrderLock
837        _cfgLocal.SplitterDistance = _cfg.SplitterDistance
838        _cfgCommon.StartupFollowers = _cfg.StartupFollowers
839        _cfgCommon.StartupKey = _cfg.StartupKey
840        _cfgCommon.StartupVersion = _cfg.StartupVersion
841        _cfgCommon.StartupApiModeNoWarning = _cfg.StartupAPImodeNoWarning
842        _cfgLocal.StatusMultiline = _cfg.StatusMultiline
843        _cfgLocal.StatusText = _cfg.StatusText
844        _cfgLocal.StatusTextHeight = _cfg.StatusTextHeight
845
846        For Each item As KeyValuePair(Of String, TabClass) In _cfg.Tabs
847            Dim tabSetting As New SettingTab
848            tabSetting.Tab = item.Value
849            tabSetting.Save()
850            _cfgCommon.TabList.Add(item.Key)
851        Next
852        _statuses.Tabs = _cfg.Tabs
853        _cfgCommon.TimelinePeriod = _cfg.TimelinePeriod
854        _cfgCommon.TinyUrlResolve = _cfg.TinyURLResolve
855        _cfgCommon.UnreadManage = _cfg.UnreadManage
856        _cfgCommon.UrlConvertAuto = _cfg.UrlConvertAuto
857        _cfgCommon.UseApi = _cfg.UseAPI
858        _cfgCommon.UsePostMethod = _cfg.UsePostMethod
859        _cfgLocal.UseRecommendStatus = _cfg.UseRecommendStatus
860        _cfgCommon.UserName = _cfg.UserName
861        _cfgCommon.UseUnreadStyle = _cfg.UseUnreadStyle
862        _cfgLocal.Width1 = _cfg.Width1
863        _cfgLocal.Width2 = _cfg.Width2
864        _cfgLocal.Width3 = _cfg.Width3
865        _cfgLocal.Width4 = _cfg.Width4
866        _cfgLocal.Width5 = _cfg.Width5
867        _cfgLocal.Width6 = _cfg.Width6
868        _cfgLocal.Width7 = _cfg.Width7
869        _cfgLocal.Width8 = _cfg.Width8
870        '念のため保存
871        _cfgCommon.Save()
872        _cfgLocal.Save()
873    End Sub
874
875    Private Sub Network_NetworkAvailabilityChanged(ByVal sender As Object, ByVal e As Devices.NetworkAvailableEventArgs)
876        If e.IsNetworkAvailable Then
877            Dim args As New GetWorkerArg()
878            PostButton.Enabled = True
879            FavAddToolStripMenuItem.Enabled = True
880            FavRemoveToolStripMenuItem.Enabled = True
881            MoveToHomeToolStripMenuItem.Enabled = True
882            MoveToFavToolStripMenuItem.Enabled = True
883            DeleteStripMenuItem.Enabled = True
884            RefreshStripMenuItem.Enabled = True
885            TimerRefreshIcon.Enabled = False
886            NotifyIcon1.Icon = NIconAt
887            If Not _initial Then
888                If SettingDialog.DMPeriodInt > 0 Then TimerDM.Enabled = True
889                If SettingDialog.TimelinePeriodInt > 0 Then TimerTimeline.Enabled = True
890                If SettingDialog.ReplyPeriodInt > 0 Then TimerReply.Enabled = True
891            Else
892                GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0)
893            End If
894        Else
895            TimerRefreshIcon.Enabled = False
896            NotifyIcon1.Icon = NIconAtSmoke
897            PostButton.Enabled = False
898            FavAddToolStripMenuItem.Enabled = False
899            FavRemoveToolStripMenuItem.Enabled = False
900            MoveToHomeToolStripMenuItem.Enabled = False
901            MoveToFavToolStripMenuItem.Enabled = False
902            DeleteStripMenuItem.Enabled = False
903            RefreshStripMenuItem.Enabled = False
904        End If
905    End Sub
906
907    Private Sub TimerTimeline_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerTimeline.Tick
908
909        If Not IsNetworkAvailable() Then Exit Sub
910
911        GetTimeline(WORKERTYPE.Timeline, 1, 0)
912    End Sub
913
914    Private Sub TimerDM_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerDM.Tick
915        GC.Collect()
916
917        If Not IsNetworkAvailable() Then Exit Sub
918
919        GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0)
920    End Sub
921
922    Private Sub TimerReply_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerReply.Tick
923        If Not IsNetworkAvailable() Then Exit Sub
924
925        GetTimeline(WORKERTYPE.Reply, 1, 0)
926    End Sub
927
928    Private Sub RefreshTimeline()
929        'スクロール制御準備
930        Dim smode As Integer = -1    '-1:制御しない,-2:最新へ,その他:topitem使用
931        Dim topId As Long = GetScrollPos(smode)
932        Dim befCnt As Integer = _curList.VirtualListSize
933
934        '現在の選択状態を退避
935        Dim selId As New Dictionary(Of String, Long())
936        Dim focusedId As New Dictionary(Of String, Long)
937        SaveSelectedStatus(selId, focusedId)
938
939        '更新確定
940        Dim notifyPosts() As PostClass = Nothing
941        Dim soundFile As String = ""
942        Dim addCount As Integer = 0
943        addCount = _statuses.SubmitUpdate(soundFile, notifyPosts)
944
945        If _endingFlag Then Exit Sub
946
947        'リストに反映&選択状態復元
948        Try
949            For Each tab As TabPage In ListTab.TabPages
950                Dim lst As DetailsListView = DirectCast(tab.Controls(0), DetailsListView)
951                Dim tabInfo As TabClass = _statuses.Tabs(tab.Text)
952                lst.BeginUpdate()
953                If lst.VirtualListSize <> tabInfo.AllCount Then
954                    If lst.Equals(_curList) Then
955                        _itemCache = Nothing
956                        _postCache = Nothing
957                    End If
958                    lst.VirtualListSize = tabInfo.AllCount 'リスト件数更新
959                    Me.SelectListItem(lst, _
960                                      _statuses.IndexOf(tab.Text, selId(tab.Text)), _
961                                      _statuses.IndexOf(tab.Text, focusedId(tab.Text)))
962                End If
963                lst.EndUpdate()
964                If tabInfo.UnreadCount > 0 AndAlso tab.ImageIndex = -1 Then tab.ImageIndex = 0 'タブアイコン
965            Next
966        Catch ex As Exception
967            ex.Data("Msg") = "Ref1, UseAPI=" + SettingDialog.UseAPI.ToString
968            Throw
969        End Try
970
971        'スクロール制御後処理
972        Try
973            If befCnt <> _curList.VirtualListSize Then
974                Select Case smode
975                    Case -3
976                        '最上行
977                        _curList.EnsureVisible(0)
978                    Case -2
979                        '最下行へ
980                        _curList.EnsureVisible(_curList.VirtualListSize - 1)
981                    Case -1
982                        '制御しない
983                    Case Else
984                        '表示位置キープ
985                        If _curList.VirtualListSize > 0 Then
986                            _curList.EnsureVisible(_curList.VirtualListSize - 1)
987                            _curList.EnsureVisible(_statuses.IndexOf(_curTab.Text, topId))
988                        End If
989                End Select
990            End If
991        Catch ex As Exception
992            ex.Data("Msg") = "Ref2, UseAPI=" + SettingDialog.UseAPI.ToString
993            Throw
994        End Try
995
996        '新着通知
997        NotifyNewPosts(notifyPosts, soundFile, addCount)
998
999        SetMainWindowTitle()
1000        If Not StatusLabelUrl.Text.StartsWith("http") Then SetStatusLabel()
1001    End Sub
1002
1003    Private Function GetScrollPos(ByRef smode As Integer) As Long
1004        Dim topId As Long = -1
1005        If _curList.VirtualListSize > 0 Then
1006            If _statuses.SortMode = IdComparerClass.ComparerMode.Id Then
1007                If _statuses.SortOrder = SortOrder.Ascending Then
1008                    'Id昇順
1009                    If ListLockMenuItem.Checked Then
1010                        '制御しない
1011                        'smode = -1
1012                        '現在表示位置へ強制スクロール
1013                        topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index)
1014                        smode = 0
1015                    Else
1016                        '最下行が表示されていたら、最下行へ強制スクロール。最下行が表示されていなかったら制御しない
1017                        Dim _item As ListViewItem
1018                        _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1)   '一番下
1019                        If _item Is Nothing Then _item = _curList.Items(_curList.Items.Count - 1)
1020                        If _item.Index = _curList.Items.Count - 1 Then
1021                            smode = -2
1022                        Else
1023                            'smode = -1
1024                            topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index)
1025                            smode = 0
1026                        End If
1027                    End If
1028                Else
1029                    'Id降順
1030                    If ListLockMenuItem.Checked Then
1031                        '現在表示位置へ強制スクロール
1032                        topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index)
1033                        smode = 0
1034                    Else
1035                        '最上行が表示されていたら、制御しない。最上行が表示されていなかったら、現在表示位置へ強制スクロール
1036                        Dim _item As ListViewItem
1037
1038                        _item = _curList.GetItemAt(0, 10)     '一番上
1039                        If _item Is Nothing Then _item = _curList.Items(0)
1040                        If _item.Index = 0 Then
1041                            smode = -3  '最上行
1042                        Else
1043                            topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index)
1044                            smode = 0
1045                        End If
1046                    End If
1047                End If
1048            Else
1049                '現在表示位置へ強制スクロール
1050                topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index)
1051                smode = 0
1052            End If
1053        Else
1054            smode = -1
1055        End If
1056        Return topId
1057    End Function
1058
1059    Private Sub SaveSelectedStatus(ByVal selId As Dictionary(Of String, Long()), ByVal focusedId As Dictionary(Of String, Long))
1060        If _endingFlag Then Exit Sub
1061        For Each tab As TabPage In ListTab.TabPages
1062            Dim lst As DetailsListView = DirectCast(tab.Controls(0), DetailsListView)
1063            If lst.SelectedIndices.Count > 0 AndAlso lst.SelectedIndices.Count < 31 Then
1064                selId.Add(tab.Text, _statuses.GetId(tab.Text, lst.SelectedIndices))
1065            Else
1066                selId.Add(tab.Text, New Long(0) {-1})
1067            End If
1068            If lst.FocusedItem IsNot Nothing Then
1069                focusedId.Add(tab.Text, _statuses.GetId(tab.Text, lst.FocusedItem.Index))
1070            Else
1071                focusedId.Add(tab.Text, -1)
1072            End If
1073        Next
1074
1075    End Sub
1076
1077    Private Sub NotifyNewPosts(ByVal notifyPosts() As PostClass, ByVal soundFile As String, ByVal addCount As Integer)
1078        '新着通知
1079        If NewPostPopMenuItem.Checked AndAlso _
1080               notifyPosts IsNot Nothing AndAlso notifyPosts.Length > 0 AndAlso _
1081               Not _initial AndAlso _
1082               ((SettingDialog.LimitBalloon AndAlso _
1083                 (Me.WindowState = FormWindowState.Minimized OrElse Not Me.Visible OrElse Form.ActiveForm Is Nothing)) _
1084                OrElse Not SettingDialog.LimitBalloon) Then
1085            Dim sb As New StringBuilder
1086            Dim reply As Boolean = False
1087            Dim dm As Boolean = False
1088            For Each post As PostClass In notifyPosts
1089                If post.IsReply Then reply = True
1090                If post.IsDm Then dm = True
1091                If sb.Length > 0 Then sb.Append(System.Environment.NewLine)
1092                Select Case SettingDialog.NameBalloon
1093                    Case NameBalloonEnum.UserID
1094                        sb.Append(post.Name).Append(" : ")
1095                    Case NameBalloonEnum.NickName
1096                        sb.Append(post.Nickname).Append(" : ")
1097                End Select
1098                sb.Append(post.Data)
1099            Next
1100            If SettingDialog.DispUsername Then NotifyIcon1.BalloonTipTitle = _username + " - " Else NotifyIcon1.BalloonTipTitle = ""
1101            If dm Then
1102                NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning
1103                NotifyIcon1.BalloonTipTitle += "Tween [DM] " + My.Resources.RefreshDirectMessageText1 + " " + addCount.ToString() + My.Resources.RefreshDirectMessageText2
1104            ElseIf reply Then
1105                NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning
1106                NotifyIcon1.BalloonTipTitle += "Tween [Reply!] " + My.Resources.RefreshTimelineText1 + " " + addCount.ToString() + My.Resources.RefreshTimelineText2
1107            Else
1108                NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info
1109                NotifyIcon1.BalloonTipTitle += "Tween " + My.Resources.RefreshTimelineText1 + " " + addCount.ToString() + My.Resources.RefreshTimelineText2
1110            End If
1111            NotifyIcon1.BalloonTipText = sb.ToString()
1112            NotifyIcon1.ShowBalloonTip(500)
1113        End If
1114
1115        'サウンド再生
1116        If Not _initial AndAlso SettingDialog.PlaySound AndAlso soundFile <> "" Then
1117            Try
1118                My.Computer.Audio.Play(Path.Combine(My.Application.Info.DirectoryPath.ToString(), soundFile), AudioPlayMode.Background)
1119            Catch ex As Exception
1120
1121            End Try
1122        End If
1123    End Sub
1124
1125    Private Sub Mylist_Scrolled(ByVal sender As Object, ByVal e As System.EventArgs)
1126        'TimerColorize.Stop()
1127        'TimerColorize.Start()
1128    End Sub
1129
1130    Private Sub MyList_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
1131        If _curList.SelectedIndices.Count <> 1 Then Exit Sub
1132        'If _curList.SelectedIndices.Count = 0 Then Exit Sub
1133
1134        _curItemIndex = _curList.SelectedIndices(0)
1135        _curPost = GetCurTabPost(_curItemIndex)
1136        If SettingDialog.UnreadManage Then _statuses.SetRead(True, _curTab.Text, _curItemIndex)
1137        'MyList.RedrawItems(MyList.SelectedIndices(0), MyList.SelectedIndices(0), False)   'RetrieveVirtualItemが発生することを期待
1138        'キャッシュの書き換え
1139        ChangeCacheStyleRead(True, _curItemIndex, _curTab)   '既読へ(フォント、文字色)
1140
1141        'ColorizeList(-1)    '全キャッシュ更新(背景色)
1142        'DispSelectedPost()
1143        ColorizeList()
1144        TimerColorize.Stop()
1145        TimerColorize.Start()
1146        'cMode = 1
1147    End Sub
1148
1149    Private Sub ChangeCacheStyleRead(ByVal Read As Boolean, ByVal Index As Integer, ByVal Tab As TabPage)
1150        'Read:True=既読 False=未読
1151        '未読管理していなかったら既読として扱う
1152        If Not _statuses.Tabs(_curTab.Text).UnreadManage OrElse _
1153           Not SettingDialog.UnreadManage Then Read = True
1154
1155        '対象の特定
1156        Dim itm As ListViewItem
1157        Dim post As PostClass
1158        If Tab.Equals(_curTab) AndAlso _itemCache IsNot Nothing AndAlso Index >= _itemCacheIndex AndAlso Index < _itemCacheIndex + _itemCache.Length Then
1159            itm = _itemCache(Index - _itemCacheIndex)
1160            post = _postCache(Index - _itemCacheIndex)
1161        Else
1162            itm = DirectCast(Tab.Controls(0), DetailsListView).Items(Index)
1163            post = _statuses.Item(Tab.Text, Index)
1164        End If
1165
1166        ChangeItemStyleRead(Read, itm, post, DirectCast(Tab.Controls(0), DetailsListView))
1167    End Sub
1168
1169    Private Sub ChangeItemStyleRead(ByVal Read As Boolean, ByVal Item As ListViewItem, ByVal Post As PostClass, ByVal DList As DetailsListView)
1170        Dim fnt As Font
1171        'フォント
1172        If Read Then
1173            fnt = _fntReaded
1174            Item.SubItems(5).Text = ""
1175        Else
1176            fnt = _fntUnread
1177            Item.SubItems(5).Text = "★"
1178        End If
1179        '文字色
1180        Dim cl As Color
1181        If Post.IsFav Then
1182            cl = _clFav
1183        ElseIf Post.IsOwl AndAlso (Post.IsDm OrElse SettingDialog.OneWayLove) Then
1184            cl = _clOWL
1185        ElseIf Read OrElse Not SettingDialog.UseUnreadStyle Then
1186            cl = _clReaded
1187        Else
1188            cl = _clUnread
1189        End If
1190        If DList Is Nothing OrElse Item.Index = -1 Then
1191            Item.ForeColor = cl
1192            If SettingDialog.UseUnreadStyle Then
1193                Item.Font = fnt
1194            End If
1195        Else
1196            DList.Update()
1197            If SettingDialog.UseUnreadStyle Then
1198                DList.ChangeItemFontAndColor(Item.Index, cl, fnt)
1199            Else
1200                DList.ChangeItemForeColor(Item.Index, cl)
1201            End If
1202            'If _itemCache IsNot Nothing Then DList.RedrawItems(_itemCacheIndex, _itemCacheIndex + _itemCache.Length - 1, False)
1203        End If
1204    End Sub
1205
1206    Private Sub ColorizeList()
1207        'Index:更新対象のListviewItem.Index。Colorを返す。
1208        '-1は全キャッシュ。Colorは返さない(ダミーを戻す)
1209        Dim _post As PostClass
1210        If _anchorFlag Then
1211            _post = _anchorPost
1212        Else
1213            _post = _curPost
1214        End If
1215
1216        If _itemCache Is Nothing Then Exit Sub
1217
1218        'For cnt As Integer = 0 To _itemCache.Length - 1
1219        '    If Not _postCache(cnt).IsRead AndAlso SettingDialog.UnreadManage AndAlso _statuses.Tabs(_curTab.Text).UnreadManage Then
1220        '        _itemCache(cnt).Font = _fntUnread
1221        '    Else
1222        '        _itemCache(cnt).Font = _fntReaded
1223        '    End If
1224        'Next
1225
1226        If _post Is Nothing Then Exit Sub
1227
1228        Try
1229            For cnt As Integer = 0 To _itemCache.Length - 1
1230                '_itemCache(cnt).BackColor = JudgeColor(_post, _postCache(cnt))
1231                _curList.ChangeItemBackColor(_itemCacheIndex + cnt, JudgeColor(_post, _postCache(cnt)))
1232            Next
1233        Catch ex As Exception
1234        End Try
1235    End Sub
1236
1237    Private Sub ColorizeList(ByVal Item As ListViewItem, ByVal Index As Integer)
1238        'Index:更新対象のListviewItem.Index。Colorを返す。
1239        '-1は全キャッシュ。Colorは返さない(ダミーを戻す)
1240        Dim _post As PostClass
1241        If _anchorFlag Then
1242            _post = _anchorPost
1243        Else
1244            _post = _curPost
1245        End If
1246
1247        Dim tPost As PostClass = GetCurTabPost(Index)
1248
1249        'If Not tPost.IsRead AndAlso SettingDialog.UnreadManage AndAlso _statuses.Tabs(_curTab.Text).UnreadManage Then
1250        '    Item.Font = _fntUnread
1251        'Else
1252        '    Item.Font = _fntReaded
1253        'End If
1254
1255        If _post Is Nothing Then Exit Sub
1256
1257        If Item.Index = -1 Then
1258            Item.BackColor = JudgeColor(_post, tPost)
1259        Else
1260            _curList.ChangeItemBackColor(Item.Index, JudgeColor(_post, tPost))
1261        End If
1262    End Sub
1263
1264    Private Function JudgeColor(ByVal BasePost As PostClass, ByVal TargetPost As PostClass) As Color
1265        Dim cl As Color
1266        If TargetPost.Id = BasePost.InReplyToId Then
1267            '@先
1268            cl = _clAtTo
1269        ElseIf TargetPost.IsMe Then
1270            '自分=発言者
1271            cl = _clSelf
1272        ElseIf TargetPost.Name.Equals(BasePost.Name, StringComparison.OrdinalIgnoreCase) Then
1273            '発言者
1274            cl = _clTarget
1275        ElseIf TargetPost.IsReply Then
1276            '自分宛返信
1277            cl = _clAtSelf
1278        ElseIf BasePost.ReplyToList.Contains(TargetPost.Name.ToLower()) Then
1279            '返信先
1280            cl = _clAtFromTarget
1281        ElseIf TargetPost.ReplyToList.Contains(BasePost.Name.ToLower()) Then
1282            'その人への返信
1283            cl = _clAtTarget
1284        Else
1285            'その他
1286            cl = System.Drawing.SystemColors.Window
1287        End If
1288        Return cl
1289    End Function
1290
1291    Private Sub PostButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PostButton.Click
1292        If StatusText.Text.Trim.Length = 0 Then
1293            DoRefresh()
1294            Exit Sub
1295        End If
1296
1297        _history(_history.Count - 1) = StatusText.Text.Trim
1298
1299        If SettingDialog.UrlConvertAuto Then UrlConvertAutoToolStripMenuItem_Click(Nothing, Nothing)
1300
1301        Dim args As New GetWorkerArg()
1302        args.page = 0
1303        args.endPage = 0
1304        args.type = WORKERTYPE.PostMessage
1305        If (StatusText.Text.StartsWith("D ")) OrElse (My.Computer.Keyboard.ShiftKeyDown) Then
1306            args.status = StatusText.Text.Trim
1307        ElseIf SettingDialog.UseRecommendStatus() Then
1308            ' 推奨ステータスを使用する
1309            Dim statregex As New Regex("^0*")
1310            args.status = StatusText.Text.Trim() + " [TWNv" + statregex.Replace(My.Application.Info.Version.Major.ToString() + My.Application.Info.Version.Minor.ToString() + My.Application.Info.Version.Build.ToString() + My.Application.Info.Version.Revision.ToString(), "") + "]"
1311        Else
1312            ' テキストボックスに入力されている文字列を使用する
1313            args.status = StatusText.Text.Trim() + " " + SettingDialog.Status.Trim()
1314        End If
1315
1316        If ToolStripMenuItemApiCommandEvasion.Checked Then
1317            ' APIコマンド回避
1318            Dim regex As New Regex("^[+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]*(get|g|fav|follow|f|on|off|stop|quit|leave|l|whois|w|nudge|n|stats|invite|track|untrack|tracks|tracking|\*)([+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]+|$)", RegexOptions.IgnoreCase)
1319            If regex.IsMatch(args.status) AndAlso args.status.EndsWith(" .") = False Then args.status += " ."
1320        End If
1321
1322        If ToolStripMenuItemUrlMultibyteSplit.Checked Then
1323            ' URLと全角文字の切り離し
1324            Dim regex2 As New Regex("https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+")
1325            Dim mc2 As Match = regex2.Match(args.status)
1326            If mc2.Success Then args.status = regex2.Replace(args.status, "$& ")
1327        End If
1328
1329        If IdeographicSpaceToSpaceToolStripMenuItem.Checked Then
1330            ' 文中の全角スペースを半角スペース2個にする
1331            args.status = args.status.Replace(" ", "  ")
1332        End If
1333
1334        RunAsync(args)
1335
1336        ListTab.SelectedTab.Controls(0).Focus()
1337    End Sub
1338
1339    Private Sub EndToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles EndToolStripMenuItem.Click
1340        _endingFlag = True
1341        Me.Close()
1342    End Sub
1343
1344    Private Sub Tween_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
1345        If Not SettingDialog.CloseToExit AndAlso e.CloseReason = CloseReason.UserClosing AndAlso _endingFlag = False Then
1346            '_endingFlag=False:フォームの×ボタン
1347            e.Cancel = True
1348            Me.Visible = False
1349        Else
1350            Try
1351                My.Application.DoEvents()
1352                Me.Cursor = Cursors.WaitCursor
1353                TimerTimeline.Enabled = False
1354                TimerReply.Enabled = False
1355                TimerDM.Enabled = False
1356                TimerColorize.Enabled = False
1357                TimerRefreshIcon.Enabled = False
1358
1359                _endingFlag = True
1360
1361                'sgenのdllがあれば不要か?
1362                If e.CloseReason <> CloseReason.WindowsShutDown AndAlso e.CloseReason <> CloseReason.TaskManagerClosing Then
1363                    SaveConfigsLocal()
1364                End If
1365
1366                For i As Integer = 0 To _bw.Length - 1
1367                    If _bw(i) IsNot Nothing AndAlso _bw(i).IsBusy Then _bw(i).CancelAsync()
1368                Next
1369
1370                Dim flg As Boolean = False
1371                Do
1372                    flg = True
1373                    For i As Integer = 0 To _bw.Length - 1
1374                        If _bw(i) IsNot Nothing AndAlso _bw(i).IsBusy Then
1375                            flg = False
1376                            Exit For
1377                        End If
1378                    Next
1379                    Threading.Thread.Sleep(500)
1380                    Application.DoEvents()
1381                Loop Until flg = True
1382
1383                Me.Visible = False
1384                NotifyIcon1.Visible = False
1385            Finally
1386                Me.Cursor = Cursors.Default
1387            End Try
1388        End If
1389    End Sub
1390
1391    Private Sub NotifyIcon1_BalloonTipClicked(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NotifyIcon1.BalloonTipClicked
1392        Me.Visible = True
1393        If Me.WindowState = FormWindowState.Minimized Then
1394            Me.WindowState = FormWindowState.Normal
1395        End If
1396        Me.Activate()
1397    End Sub
1398
1399    Private Sub GetTimelineWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
1400        Dim bw As BackgroundWorker = DirectCast(sender, BackgroundWorker)
1401        If bw.CancellationPending OrElse _endingFlag Then
1402            e.Cancel = True
1403            Exit Sub
1404        End If
1405
1406        Threading.Thread.CurrentThread.Priority = Threading.ThreadPriority.BelowNormal
1407
1408        My.Application.InitCulture()
1409        Dim ret As String = ""
1410        Dim rslt As New GetWorkerResult()
1411
1412        Dim read As Boolean = Not SettingDialog.UnreadManage
1413        If _initial AndAlso SettingDialog.UnreadManage Then read = SettingDialog.Readed
1414
1415        Dim args As GetWorkerArg = DirectCast(e.Argument, GetWorkerArg)
1416
1417
1418        If args.type <> WORKERTYPE.OpenUri Then bw.ReportProgress(0, "") 'Notifyアイコンアニメーション開始
1419
1420        Select Case args.type
1421            Case WORKERTYPE.Timeline, WORKERTYPE.Reply
1422                bw.ReportProgress(50, MakeStatusMessage(args, False))
1423                If SettingDialog.UseAPI Then
1424                    ret = Twitter.GetTimelineApi(read, args.type)
1425                Else
1426                    ret = Twitter.GetTimeline(args.page, read, args.endPage, args.type, rslt.newDM)
1427                End If
1428                rslt.addCount = _statuses.DistributePosts()
1429            Case WORKERTYPE.DirectMessegeRcv    '送信分もまとめて取得
1430                bw.ReportProgress(50, MakeStatusMessage(args, False))
1431                If SettingDialog.UseAPI Then
1432                    ret = Twitter.GetDirectMessageApi(read, WORKERTYPE.DirectMessegeRcv)
1433                    If ret = "" Then ret = Twitter.GetDirectMessageApi(read, WORKERTYPE.DirectMessegeSnt)
1434                Else
1435                    ret = Twitter.GetDirectMessage(args.page, read, args.endPage, args.type)
1436                End If
1437                rslt.addCount = _statuses.DistributePosts()
1438            Case WORKERTYPE.FavAdd
1439                'スレッド処理はしない
1440                For i As Integer = 0 To args.ids.Count - 1
1441                    Dim post As PostClass = _statuses.Item(args.ids(i))
1442                    args.page = i + 1
1443                    bw.ReportProgress(50, MakeStatusMessage(args, False))
1444                    If Not post.IsFav Then
1445                        ret = Twitter.PostFavAdd(post.Id)
1446                        If ret.Length = 0 Then
1447                            args.sIds.Add(post.Id)
1448                            post.IsFav = True    'リスト再描画必要
1449                            _favTimestamps.Add(Now)
1450                            _statuses.Tabs.Item(DEFAULTTAB.FAV).Add(post.Id, post.IsRead, False)
1451                        End If
1452                    End If
1453                Next
1454                rslt.sIds = args.sIds
1455            Case WORKERTYPE.FavRemove
1456                'スレッド処理はしない
1457                For i As Integer = 0 To args.ids.Count - 1
1458                    Dim post As PostClass = _statuses.Item(args.ids(i))
1459                    args.page = i + 1
1460                    bw.ReportProgress(50, MakeStatusMessage(args, False))
1461                    If post.IsFav Then
1462                        ret = Twitter.PostFavRemove(post.Id)
1463                        If ret.Length = 0 Then
1464                            args.sIds.Add(post.Id)
1465                            post.IsFav = False    'リスト再描画必要
1466                        End If
1467                    End If
1468                Next
1469                rslt.sIds = args.sIds
1470                ' Contributed by shuyoko <http://twitter.com/shuyoko> BEGIN:
1471            Case WORKERTYPE.BlackFavAdd
1472                'スレッド処理はしない
1473                For i As Integer = 0 To args.ids.Count - 1
1474                    Dim post As PostClass = _statuses.Item(args.ids(i))
1475                    Dim blackid As Long = 0
1476                    args.page = i + 1
1477                    bw.ReportProgress(50, MakeStatusMessage(args, False))
1478                    If Not post.IsFav Then
1479                        ret = Twitter.GetBlackFavId(post.Id, blackid)
1480                        If ret.Length = 0 Then
1481                            ret = Twitter.PostFavAdd(blackid)
1482                            If ret.Length = 0 Then
1483                                args.sIds.Add(post.Id)
1484                                post.IsFav = True    'リスト再描画必要
1485                                _favTimestamps.Add(Now)
1486                            End If
1487                        End If
1488                    End If
1489                Next
1490                rslt.sIds = args.sIds
1491                ' Contributed by shuyoko <http://twitter.com/shuyoko> END.
1492            Case WORKERTYPE.PostMessage
1493                bw.ReportProgress(200)
1494                CheckReplyTo(args.status)
1495                For i As Integer = 0 To 1
1496                    ret = Twitter.PostStatus(args.status, _reply_to_id)
1497                    If ret = "" OrElse ret.StartsWith("Outputz:") Then Exit For
1498                Next
1499                _reply_to_id = 0
1500                _reply_to_name = Nothing
1501                bw.ReportProgress(300)
1502            Case WORKERTYPE.Follower
1503                bw.ReportProgress(50, My.Resources.UpdateFollowersMenuItem1_ClickText1)
1504                If SettingDialog.UseAPI Then
1505                    ret = Twitter.GetFollowersApi()
1506                Else
1507                    ret = Twitter.GetFollowers(False)       ' Followersリストキャッシュ有効
1508                End If
1509                Twitter.RefreshOwl()    '洗い換え
1510            Case WORKERTYPE.OpenUri
1511                Dim myPath As String = Convert.ToString(args.status)
1512
1513                Try
1514                    If SettingDialog.BrowserPath <> "" Then
1515                        Shell(SettingDialog.BrowserPath & " " & myPath)
1516                    Else
1517                        System.Diagnostics.Process.Start(myPath)
1518                    End If
1519                Catch ex As Exception
1520                    '                MessageBox.Show("ブラウザの起動に失敗、またはタイムアウトしました。" + ex.ToString())
1521                End Try
1522        End Select
1523
1524        'キャンセル要求
1525        If bw.CancellationPending Then
1526            e.Cancel = True
1527            Exit Sub
1528        End If
1529
1530        '時速表示用
1531        If args.type = WORKERTYPE.FavAdd OrElse args.type = WORKERTYPE.BlackFavAdd Then
1532            Dim oneHour As Date = Now.Subtract(New TimeSpan(1, 0, 0))
1533            For i As Integer = _favTimestamps.Count - 1 To 0 Step -1
1534                If _favTimestamps(i).CompareTo(oneHour) < 0 Then
1535                    _favTimestamps.RemoveAt(i)
1536                End If
1537            Next
1538        End If
1539        If args.type = WORKERTYPE.Timeline AndAlso Not _initial Then
1540            SyncLock _syncObject
1541                Dim tm As Date = Now
1542                If _tlTimestamps.ContainsKey(tm) Then
1543                    _tlTimestamps(tm) += rslt.addCount
1544                Else
1545                    _tlTimestamps.Add(Now, rslt.addCount)
1546                End If
1547                Dim oneHour As Date = Now.Subtract(New TimeSpan(1, 0, 0))
1548                Dim keys As New List(Of Date)
1549                _tlCount = 0
1550                For Each key As Date In _tlTimestamps.Keys
1551                    If key.CompareTo(oneHour) < 0 Then
1552                        keys.Add(key)
1553                    Else
1554                        _tlCount += _tlTimestamps(key)
1555                    End If
1556                Next
1557                For Each key As Date In keys
1558                    _tlTimestamps.Remove(key)
1559                Next
1560                keys.Clear()
1561            End SyncLock
1562        End If
1563
1564        '終了ステータス
1565        If args.type <> WORKERTYPE.OpenUri Then bw.ReportProgress(100, MakeStatusMessage(args, True)) 'ステータス書き換え、Notifyアイコンアニメーション開始
1566
1567        rslt.retMsg = ret
1568        rslt.type = args.type
1569        rslt.tName = args.tName
1570        If args.type = WORKERTYPE.DirectMessegeRcv OrElse _
1571           args.type = WORKERTYPE.DirectMessegeSnt OrElse _
1572           args.type = WORKERTYPE.Reply OrElse _
1573           args.type = WORKERTYPE.Timeline Then
1574            rslt.page = args.page - 1   '値が正しいか後でチェック。10ページ毎の継続確認
1575        End If
1576
1577        e.Result = rslt
1578
1579    End Sub
1580
1581    Private Function MakeStatusMessage(ByVal AsyncArg As GetWorkerArg, ByVal Finish As Boolean) As String
1582        Dim smsg As String = ""
1583        If Not Finish Then
1584            '継続中メッセージ
1585            Select Case AsyncArg.type
1586                Case WORKERTYPE.Timeline
1587                    smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText5 + AsyncArg.page.ToString() + My.Resources.GetTimelineWorker_RunWorkerCompletedText6
1588                Case WORKERTYPE.Reply
1589                    smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText4 + AsyncArg.page.ToString() + My.Resources.GetTimelineWorker_RunWorkerCompletedText6
1590                Case WORKERTYPE.DirectMessegeRcv
1591                    smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText8 + AsyncArg.page.ToString() + My.Resources.GetTimelineWorker_RunWorkerCompletedText6
1592                    'Case WORKERTYPE.DirectMessegeSnt
1593                    '    smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText12 + AsyncArg.page.ToString() + My.Resources.GetTimelineWorker_RunWorkerCompletedText6
1594                Case WORKERTYPE.FavAdd
1595                    smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText15 + AsyncArg.page.ToString() + "/" + AsyncArg.ids.Count.ToString() + _
1596                                        My.Resources.GetTimelineWorker_RunWorkerCompletedText16 + (AsyncArg.page - AsyncArg.sIds.Count - 1).ToString()
1597                Case WORKERTYPE.FavRemove
1598                    smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText17 + AsyncArg.page.ToString() + "/" + AsyncArg.ids.Count.ToString() + _
1599                                        My.Resources.GetTimelineWorker_RunWorkerCompletedText18 + (AsyncArg.page - AsyncArg.sIds.Count - 1).ToString()
1600                Case WORKERTYPE.BlackFavAdd
1601                    smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText15_black + AsyncArg.page.ToString() + "/" + AsyncArg.ids.Count.ToString() + _
1602                                        My.Resources.GetTimelineWorker_RunWorkerCompletedText16 + (AsyncArg.page - AsyncArg.sIds.Count - 1).ToString()
1603            End Select
1604        Else
1605            '完了メッセージ
1606            Select Case AsyncArg.type
1607                Case WORKERTYPE.Timeline
1608                    smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText1
1609                Case WORKERTYPE.Reply
1610                    smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText9
1611                Case WORKERTYPE.DirectMessegeRcv
1612                    smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText11
1613                Case WORKERTYPE.DirectMessegeSnt
1614                    smsg = My.Resources.GetTimelineWorker_RunWorkerCompletedText13
1615                Case WORKERTYPE.FavAdd
1616                    '進捗メッセージ残す
1617                Case WORKERTYPE.FavRemove
1618                    '進捗メッセージ残す
1619                Case WORKERTYPE.BlackFavAdd
1620                    '進捗メッセージ残す
1621            End Select
1622        End If
1623        Return smsg
1624    End Function
1625
1626    Private Sub GetTimelineWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs)
1627        If _endingFlag Then Exit Sub
1628        If e.ProgressPercentage > 100 Then
1629            '発言投稿
1630            If e.ProgressPercentage = 200 Then    '開始
1631                StatusLabel.Text = "Posting..."
1632                StatusText.Enabled = False
1633                PostButton.Enabled = False
1634                ReplyStripMenuItem.Enabled = False
1635                DMStripMenuItem.Enabled = False
1636            End If
1637            If e.ProgressPercentage = 300 Then  '終了
1638                StatusLabel.Text = My.Resources.PostWorker_RunWorkerCompletedText4
1639                StatusText.Enabled = True
1640                PostButton.Enabled = True
1641                ReplyStripMenuItem.Enabled = True
1642                DMStripMenuItem.Enabled = True
1643                NotifyIcon1.Icon = NIconAt
1644            End If
1645        Else
1646            Dim smsg As String = DirectCast(e.UserState, String)
1647            If smsg.Length > 0 Then StatusLabel.Text = smsg
1648            If e.ProgressPercentage = 0 Then    '開始
1649                TimerRefreshIcon.Enabled = True
1650            End If
1651            If e.ProgressPercentage = 100 Then  '終了
1652                Dim cnt As Integer = 0
1653                For Each bw As BackgroundWorker In _bw
1654                    If bw IsNot Nothing AndAlso bw.IsBusy Then cnt += 1
1655                Next
1656                If cnt < 2 Then
1657                    TimerRefreshIcon.Enabled = False
1658                    NotifyIcon1.Icon = NIconAt
1659                End If
1660            End If
1661        End If
1662    End Sub
1663
1664    Private Sub GetTimelineWorker_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
1665
1666        If _endingFlag OrElse e.Cancelled Then Exit Sub 'キャンセル
1667
1668        Dim nw As Boolean = IsNetworkAvailable()
1669
1670        If e.Error IsNot Nothing Then
1671            If nw Then NotifyIcon1.Icon = NIconAtRed
1672            Dim buf As String = Nothing
1673            Throw New Exception("BackgroundWorker Exception", e.Error)
1674            _waitTimeline = False
1675            _waitReply = False
1676            _waitFollower = False
1677            _waitDm = False
1678            '_initial = False
1679            Exit Sub
1680        End If
1681
1682        Dim rslt As GetWorkerResult = DirectCast(e.Result, GetWorkerResult)
1683        Dim args As New GetWorkerArg()
1684
1685        If rslt.type = WORKERTYPE.OpenUri Then Exit Sub
1686
1687        If nw Then
1688            NotifyIcon1.Icon = NIconAt
1689            'タイマー再始動
1690            If SettingDialog.TimelinePeriodInt > 0 AndAlso Not TimerTimeline.Enabled Then TimerTimeline.Enabled = True
1691            If SettingDialog.DMPeriodInt > 0 AndAlso Not TimerDM.Enabled Then TimerDM.Enabled = True
1692            If SettingDialog.ReplyPeriodInt > 0 AndAlso Not TimerReply.Enabled Then TimerReply.Enabled = True
1693        Else
1694            NotifyIcon1.Icon = NIconAtSmoke
1695        End If
1696
1697        'エラー
1698        If rslt.retMsg.Length > 0 Then
1699            If nw Then NotifyIcon1.Icon = NIconAtRed
1700            StatusLabel.Text = rslt.retMsg
1701        End If
1702
1703        If rslt.type = WORKERTYPE.FavRemove Then
1704            DispSelectedPost()          ' 詳細画面書き直し
1705            For Each i As Long In rslt.sIds
1706                _statuses.RemovePost(DEFAULTTAB.FAV, i)
1707            Next
1708            If _curTab.Text.Equals(DEFAULTTAB.FAV) Then
1709                _itemCache = Nothing    'キャッシュ破棄
1710                _postCache = Nothing
1711                _curPost = Nothing
1712                _curItemIndex = -1
1713            End If
1714            For Each tp As TabPage In ListTab.TabPages
1715                If tp.Text = DEFAULTTAB.FAV Then
1716                    DirectCast(tp.Controls(0), DetailsListView).VirtualListSize = _statuses.Tabs(DEFAULTTAB.FAV).AllCount
1717                    Exit For
1718                End If
1719            Next
1720        End If
1721
1722        'リストに反映
1723        Dim busy As Boolean = False
1724        For Each bw As BackgroundWorker In _bw
1725            If bw IsNot Nothing AndAlso bw.IsBusy Then
1726                busy = True
1727                Exit For
1728            End If
1729        Next
1730        If Not busy Then RefreshTimeline() 'background処理なければ、リスト反映
1731
1732        Select Case rslt.type
1733            Case WORKERTYPE.Timeline
1734                _waitTimeline = False
1735                If Not _initial Then
1736                    '通常時
1737                    '自動調整
1738                    If Not SettingDialog.UseAPI Then
1739                        If SettingDialog.PeriodAdjust AndAlso SettingDialog.TimelinePeriodInt > 0 Then
1740                            If rslt.addCount >= 20 Then
1741                                Dim itv As Integer = TimerTimeline.Interval
1742                                itv -= 5000
1743                                If itv < 15000 Then itv = 15000
1744                                TimerTimeline.Interval = itv
1745                            Else
1746                                TimerTimeline.Interval += 1000
1747                                If TimerTimeline.Interval > SettingDialog.TimelinePeriodInt * 1000 Then TimerTimeline.Interval = SettingDialog.TimelinePeriodInt * 1000
1748                            End If
1749                        End If
1750                        If rslt.newDM Then
1751                            GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0)
1752                        End If
1753                    Else
1754                        'API使用時の取得調整は別途考える(カウント調整?)
1755                    End If
1756                End If
1757            Case WORKERTYPE.Reply
1758                _waitReply = False
1759                If rslt.newDM AndAlso Not _initial Then
1760                    GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0)
1761                End If
1762            Case WORKERTYPE.DirectMessegeRcv
1763                _waitDm = False
1764            Case WORKERTYPE.FavAdd, WORKERTYPE.BlackFavAdd, WORKERTYPE.FavRemove
1765                _curList.BeginUpdate()
1766                If rslt.type = WORKERTYPE.FavRemove AndAlso _curTab.Text.Equals(DEFAULTTAB.FAV) Then
1767                    '色変えは不要
1768                Else
1769                    For i As Integer = 0 To rslt.sIds.Count - 1
1770                        If _curTab.Text.Equals(rslt.tName) Then
1771                            Dim idx As Integer = _statuses.Tabs(rslt.tName).IndexOf(rslt.sIds(i))
1772                            Dim post As PostClass = _statuses.Item(rslt.sIds(i))
1773                            ChangeCacheStyleRead(post.IsRead, idx, _curTab)
1774                            If idx = _curItemIndex Then DispSelectedPost() '選択アイテム再表示
1775                        End If
1776                    Next
1777                End If
1778                _curList.EndUpdate()
1779            Case WORKERTYPE.PostMessage
1780                urlUndoBuffer = Nothing
1781                UrlUndoToolStripMenuItem.Enabled = False  'Undoをできないように設定
1782
1783                If rslt.retMsg.Length > 0 AndAlso Not rslt.retMsg.StartsWith("Outputz") Then
1784                    StatusLabel.Text = rslt.retMsg
1785                Else
1786                    _postTimestamps.Add(Now)
1787                    Dim oneHour As Date = Now.Subtract(New TimeSpan(1, 0, 0))
1788                    For i As Integer = _postTimestamps.Count - 1 To 0 Step -1
1789                        If _postTimestamps(i).CompareTo(oneHour) < 0 Then
1790                            _postTimestamps.RemoveAt(i)
1791                        End If
1792                    Next
1793
1794                    If rslt.retMsg.Length > 0 Then StatusLabel.Text = rslt.retMsg 'Outputz失敗時
1795
1796                    StatusText.Text = ""
1797                    _history.Add("")
1798                    _hisIdx = _history.Count - 1
1799                    SetMainWindowTitle()
1800                End If
1801                If rslt.retMsg.Length = 0 AndAlso SettingDialog.PostAndGet Then GetTimeline(WORKERTYPE.Timeline, 1, 0)
1802            Case WORKERTYPE.Follower
1803                _waitFollower = False
1804                _itemCache = Nothing
1805                _postCache = Nothing
1806                _curList.Refresh()
1807        End Select
1808
1809    End Sub
1810
1811    Private Sub GetTimeline(ByVal WkType As WORKERTYPE, ByVal fromPage As Integer, ByVal toPage As Integer)
1812        'toPage=0:通常モード
1813        If Not IsNetworkAvailable() Then Exit Sub
1814        'タイマー停止
1815        If SettingDialog.UseAPI Then
1816            Select Case WkType
1817                Case WORKERTYPE.Timeline
1818                    TimerTimeline.Enabled = False
1819                Case WORKERTYPE.Reply
1820                    TimerReply.Enabled = False
1821                Case WORKERTYPE.DirectMessegeRcv, WORKERTYPE.DirectMessegeSnt
1822                    TimerDM.Enabled = False
1823            End Select
1824        Else
1825            Select Case WkType
1826                Case WORKERTYPE.Timeline
1827                    TimerTimeline.Enabled = False
1828                Case WORKERTYPE.Reply
1829                    TimerReply.Enabled = False
1830                Case WORKERTYPE.DirectMessegeRcv, WORKERTYPE.DirectMessegeSnt
1831                    TimerDM.Enabled = False
1832            End Select
1833        End If
1834        '非同期実行引数設定
1835        Dim args As New GetWorkerArg
1836        args.page = fromPage
1837        args.endPage = toPage
1838        args.type = WkType
1839
1840        RunAsync(args)
1841
1842        'Timeline取得モードの場合はReplyも同時に取得
1843        If Not SettingDialog.UseAPI AndAlso _
1844           Not _initial AndAlso _
1845           WkType = WORKERTYPE.Timeline AndAlso _
1846           SettingDialog.CheckReply Then
1847            TimerReply.Enabled = False
1848            Dim _args As New GetWorkerArg
1849            _args.page = fromPage
1850            _args.endPage = toPage
1851            _args.type = WORKERTYPE.Reply
1852            RunAsync(_args)
1853        End If
1854    End Sub
1855
1856    Private Function NextPageMessage(ByVal page As Integer) As DialogResult
1857        Dim flashRslt As Integer = Win32Api.FlashWindow(Me.Handle.ToInt32, 1)
1858        Return MessageBox.Show((page * 20).ToString + My.Resources.GetTimelineWorker_RunWorkerCompletedText2, _
1859                           My.Resources.GetTimelineWorker_RunWorkerCompletedText3, _
1860                           MessageBoxButtons.YesNo, _
1861                           MessageBoxIcon.Question)
1862    End Function
1863
1864    Private Sub NotifyIcon1_MouseClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.MouseClick
1865        If e.Button = Windows.Forms.MouseButtons.Left Then
1866            Me.Visible = True
1867            If Me.WindowState = FormWindowState.Minimized Then
1868                Me.WindowState = FormWindowState.Normal
1869            End If
1870            Me.Activate()
1871        End If
1872    End Sub
1873
1874    Private Sub MyList_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
1875        MakeReplyOrDirectStatus()
1876    End Sub
1877
1878    Private Sub FavAddToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FavAddToolStripMenuItem.Click
1879        If _curTab.Text = DEFAULTTAB.DM OrElse _curList.SelectedIndices.Count = 0 Then Exit Sub
1880
1881        '複数fav確認msg
1882        If _curList.SelectedIndices.Count > 1 Then
1883            If MessageBox.Show(My.Resources.FavAddToolStripMenuItem_ClickText1, My.Resources.FavAddToolStripMenuItem_ClickText2, _
1884                               MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
1885                Exit Sub
1886            End If
1887        End If
1888
1889        Dim args As New GetWorkerArg
1890        args.ids = New List(Of Long)
1891        args.sIds = New List(Of Long)
1892        args.tName = _curTab.Text
1893        args.type = WORKERTYPE.FavAdd
1894        For Each idx As Integer In _curList.SelectedIndices
1895            Dim post As PostClass = GetCurTabPost(idx)
1896            If Not post.IsFav Then args.ids.Add(post.Id)
1897        Next
1898        If args.ids.Count = 0 Then
1899            StatusLabel.Text = My.Resources.FavAddToolStripMenuItem_ClickText4
1900            Exit Sub
1901        End If
1902
1903        RunAsync(args)
1904    End Sub
1905
1906    Private Sub FavRemoveToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FavRemoveToolStripMenuItem.Click
1907        If _curTab.Text = DEFAULTTAB.DM OrElse _curList.SelectedIndices.Count = 0 Then Exit Sub
1908
1909        If _curList.SelectedIndices.Count > 1 Then
1910            If MessageBox.Show(My.Resources.FavRemoveToolStripMenuItem_ClickText1, My.Resources.FavRemoveToolStripMenuItem_ClickText2, _
1911                               MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
1912                Exit Sub
1913            End If
1914        End If
1915
1916        Dim args As New GetWorkerArg()
1917        args.ids = New List(Of Long)()
1918        args.sIds = New List(Of Long)()
1919        args.tName = _curTab.Text
1920        args.type = WORKERTYPE.FavRemove
1921        For Each idx As Integer In _curList.SelectedIndices
1922            Dim post As PostClass = GetCurTabPost(idx)
1923            If post.IsFav Then args.ids.Add(post.Id)
1924        Next
1925        If args.ids.Count = 0 Then
1926            StatusLabel.Text = My.Resources.FavRemoveToolStripMenuItem_ClickText4
1927            Exit Sub
1928        End If
1929
1930        RunAsync(args)
1931    End Sub
1932
1933    Private Function GetCurTabPost(ByVal Index As Integer) As PostClass
1934        If _postCache IsNot Nothing AndAlso Index >= _itemCacheIndex AndAlso Index < _itemCacheIndex + _postCache.Length Then
1935            Return _postCache(Index - _itemCacheIndex)
1936        Else
1937            Return _statuses.Item(_curTab.Text, Index)
1938        End If
1939    End Function
1940
1941
1942    Private Sub MoveToHomeToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MoveToHomeToolStripMenuItem.Click
1943        If _curList.SelectedIndices.Count > 0 Then
1944            OpenUriAsync("http://twitter.com/" + GetCurTabPost(_curList.SelectedIndices(0)).Name)
1945        End If
1946    End Sub
1947
1948    Private Sub MoveToFavToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MoveToFavToolStripMenuItem.Click
1949        If _curList.SelectedIndices.Count > 0 Then
1950            OpenUriAsync("http://twitter.com/" + GetCurTabPost(_curList.SelectedIndices(0)).Name + "/favorites")
1951        End If
1952    End Sub
1953
1954    Private Sub Tween_ClientSizeChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.ClientSizeChanged
1955        'ショートカットから最小化状態で起動した際の対応
1956        Static initialize As Boolean = False
1957
1958        If Me.WindowState <> FormWindowState.Minimized Then
1959            If initialize Then
1960                If Me.WindowState = FormWindowState.Normal Then
1961                    _mySize = Me.ClientSize
1962                    _mySpDis = Me.SplitContainer1.SplitterDistance
1963                    If StatusText.Multiline Then _mySpDis2 = Me.StatusText.Height
1964                End If
1965            ElseIf _cfgLocal IsNot Nothing Then
1966                '初回フォームレイアウト復元
1967                Try
1968                    Me.SplitContainer1.SplitterDistance = _cfgLocal.SplitterDistance     'Splitterの位置設定
1969                    '発言欄複数行
1970                    StatusText.Multiline = _cfgLocal.StatusMultiline
1971                    If StatusText.Multiline Then
1972                        SplitContainer2.SplitterDistance = SplitContainer2.Height - _cfgLocal.StatusTextHeight - SplitContainer2.SplitterWidth
1973                    Else
1974                        SplitContainer2.SplitterDistance = SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth
1975                    End If
1976                    initialize = True
1977                Catch ex As Exception
1978                End Try
1979            End If
1980        End If
1981    End Sub
1982
1983    Private Sub MyList_ColumnClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs)
1984        If SettingDialog.SortOrderLock Then Exit Sub
1985        Dim mode As IdComparerClass.ComparerMode
1986        If _iconCol Then
1987            mode = IdComparerClass.ComparerMode.Id
1988        Else
1989            Select Case e.Column
1990                Case 0, 5, 6    '0:アイコン,5:未読マーク,6:プロテクト・フィルターマーク
1991                    'ソートしない
1992                    Exit Sub
1993                Case 1  'ニックネーム
1994                    mode = IdComparerClass.ComparerMode.Nickname
1995                Case 2  '本文
1996                    mode = IdComparerClass.ComparerMode.Data
1997                Case 3  '時刻=発言Id
1998                    mode = IdComparerClass.ComparerMode.Id
1999                Case 4  '名前
2000                    mode = IdComparerClass.ComparerMode.Name
2001                Case 7  'Source
2002                    mode = IdComparerClass.ComparerMode.Source
2003            End Select
2004        End If
2005        _statuses.ToggleSortOrder(mode)
2006        _itemCache = Nothing
2007        _postCache = Nothing
2008        _curList.Refresh()
2009    End Sub
2010
2011    Private Sub Tween_LocationChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LocationChanged
2012        If Me.WindowState = FormWindowState.Normal Then
2013            _myLoc = Me.DesktopLocation
2014        End If
2015    End Sub
2016
2017    Private Sub ContextMenuStrip2_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip2.Opening
2018        If ListTab.SelectedTab.Text = DEFAULTTAB.DM Then
2019            FavAddToolStripMenuItem.Enabled = False
2020            FavRemoveToolStripMenuItem.Enabled = False
2021            StatusOpenMenuItem.Enabled = False
2022            FavorareMenuItem.Enabled = False
2023            BlackFavAddToolStripMenuItem.Enabled = False
2024            'BlackFavRemoveToolStripMenuItem.Enabled = False
2025        Else
2026            If IsNetworkAvailable() Then
2027                FavAddToolStripMenuItem.Enabled = True
2028                FavRemoveToolStripMenuItem.Enabled = True
2029                StatusOpenMenuItem.Enabled = True
2030                FavorareMenuItem.Enabled = True
2031                BlackFavAddToolStripMenuItem.Enabled = True
2032                'BlackFavRemoveToolStripMenuItem.Enabled = True
2033            End If
2034        End If
2035        If _curPost Is Nothing OrElse (_curPost.IsDm OrElse SettingDialog.ProtectNotInclude AndAlso _curPost.IsProtect) Then
2036            ReTweetStripMenuItem.Enabled = False
2037        Else
2038            ReTweetStripMenuItem.Enabled = True
2039        End If
2040    End Sub
2041
2042    Private Sub ReplyStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReplyStripMenuItem.Click
2043        MakeReplyOrDirectStatus(False, True)
2044    End Sub
2045
2046    Private Sub DMStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DMStripMenuItem.Click
2047        MakeReplyOrDirectStatus(False, False)
2048    End Sub
2049
2050    Private Sub DeleteStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DeleteStripMenuItem.Click
2051        If _curTab.Text <> DEFAULTTAB.DM Then
2052            Dim myPost As Boolean = False
2053            For Each idx As Integer In _curList.SelectedIndices
2054                If GetCurTabPost(idx).IsMe Then
2055                    myPost = True
2056                    Exit For
2057                End If
2058            Next
2059            If Not myPost Then Exit Sub
2060        End If
2061
2062        Dim tmp As String = String.Format(My.Resources.DeleteStripMenuItem_ClickText1, Environment.NewLine)
2063
2064        If MessageBox.Show(tmp, My.Resources.DeleteStripMenuItem_ClickText2, _
2065              MessageBoxButtons.OKCancel, _
2066              MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then Exit Sub
2067
2068        Dim fidx As Integer
2069        If _curList.FocusedItem IsNot Nothing Then
2070            fidx = _curList.FocusedItem.Index
2071        ElseIf _curList.TopItem IsNot Nothing Then
2072            fidx = _curList.TopItem.Index
2073        Else
2074            fidx = 0
2075        End If
2076
2077        Try
2078            Me.Cursor = Cursors.WaitCursor
2079
2080            Dim rslt As Boolean = True
2081            For Each Id As Long In _statuses.GetId(_curTab.Text, _curList.SelectedIndices)
2082                Dim rtn As String = ""
2083                If _curTab.Text = DEFAULTTAB.DM Then
2084                    rtn = Twitter.RemoveDirectMessage(Id)
2085                Else
2086                    If _statuses.Item(Id).IsMe Then
2087                        rtn = Twitter.RemoveStatus(Id)
2088                    Else
2089                        Continue For
2090                    End If
2091                End If
2092                If rtn.Length > 0 Then
2093                    'エラー
2094                    rslt = False
2095                Else
2096                    _statuses.RemovePost(Id)
2097                End If
2098            Next
2099
2100            If Not rslt Then
2101                StatusLabel.Text = My.Resources.DeleteStripMenuItem_ClickText3  '失敗
2102            Else
2103                StatusLabel.Text = My.Resources.DeleteStripMenuItem_ClickText4  '成功
2104            End If
2105
2106            _itemCache = Nothing    'キャッシュ破棄
2107            _postCache = Nothing
2108            _curPost = Nothing
2109            _curItemIndex = -1
2110            For Each tb As TabPage In ListTab.TabPages
2111                DirectCast(tb.Controls(0), DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
2112                If _curTab.Equals(tb) Then
2113                    _curList.SelectedIndices.Clear()
2114                    If _statuses.Tabs(tb.Text).AllCount > 0 Then
2115                        If _statuses.Tabs(tb.Text).AllCount - 1 > fidx AndAlso fidx > -1 Then
2116                            _curList.SelectedIndices.Add(fidx)
2117                        Else
2118                            _curList.SelectedIndices.Add(_statuses.Tabs(tb.Text).AllCount - 1)
2119                        End If
2120                        If _curList.SelectedIndices.Count > 0 Then
2121                            _curList.EnsureVisible(_curList.SelectedIndices(0))
2122                            _curList.FocusedItem = _curList.Items(_curList.SelectedIndices(0))
2123                        End If
2124                    End If
2125                End If
2126                If _statuses.Tabs(tb.Text).UnreadCount = 0 AndAlso tb.ImageIndex = 0 Then tb.ImageIndex = -1
2127            Next
2128        Finally
2129            Me.Cursor = Cursors.Default
2130        End Try
2131    End Sub
2132
2133    Private Sub ReadedStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReadedStripMenuItem.Click
2134        _curList.BeginUpdate()
2135        If SettingDialog.UnreadManage Then
2136            For Each idx As Integer In _curList.SelectedIndices
2137                _statuses.SetRead(True, _curTab.Text, idx)
2138            Next
2139        End If
2140        For Each idx As Integer In _curList.SelectedIndices
2141            ChangeCacheStyleRead(True, idx, _curTab)
2142        Next
2143        ColorizeList()
2144        _curList.EndUpdate()
2145        For Each tb As TabPage In ListTab.TabPages
2146            If _statuses.Tabs(tb.Text).UnreadCount = 0 AndAlso tb.ImageIndex = 0 Then tb.ImageIndex = -1
2147        Next
2148    End Sub
2149
2150    Private Sub UnreadStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UnreadStripMenuItem.Click
2151        _curList.BeginUpdate()
2152        If SettingDialog.UnreadManage Then
2153            For Each idx As Integer In _curList.SelectedIndices
2154                _statuses.SetRead(False, _curTab.Text, idx)
2155            Next
2156        End If
2157        For Each idx As Integer In _curList.SelectedIndices
2158            ChangeCacheStyleRead(False, idx, _curTab)
2159        Next
2160        ColorizeList()
2161        _curList.EndUpdate()
2162        For Each tb As TabPage In ListTab.TabPages
2163            If _statuses.Tabs(tb.Text).UnreadCount > 0 AndAlso tb.ImageIndex = -1 Then tb.ImageIndex = 0
2164        Next
2165    End Sub
2166
2167    Private Sub RefreshStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RefreshStripMenuItem.Click
2168        DoRefresh()
2169    End Sub
2170
2171    Private Sub DoRefresh()
2172        Select Case _curTab.Text
2173            Case DEFAULTTAB.REPLY
2174                GetTimeline(WORKERTYPE.Reply, 1, 0)
2175            Case DEFAULTTAB.DM
2176                GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, 0)
2177            Case Else
2178                GetTimeline(WORKERTYPE.Timeline, 1, 0)
2179        End Select
2180    End Sub
2181
2182    Private Sub SettingStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SettingStripMenuItem.Click
2183        Dim chgUseApi As Boolean = False
2184
2185        If SettingDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
2186            SyncLock _syncObject
2187                _username = SettingDialog.UserID
2188                _password = SettingDialog.PasswordStr
2189                Twitter.Username = _username
2190                Twitter.Password = _password
2191                If SettingDialog.TimelinePeriodInt > 0 Then
2192                    If SettingDialog.PeriodAdjust AndAlso Not SettingDialog.UseAPI Then
2193                        If SettingDialog.TimelinePeriodInt * 1000 < TimerTimeline.Interval Then
2194                            TimerTimeline.Interval = SettingDialog.TimelinePeriodInt * 1000
2195                        End If
2196                    Else
2197                        TimerTimeline.Interval = SettingDialog.TimelinePeriodInt * 1000
2198                    End If
2199                    TimerTimeline.Enabled = True
2200                Else
2201                    TimerTimeline.Interval = 600000
2202                    TimerTimeline.Enabled = False
2203                End If
2204                If SettingDialog.ReplyPeriodInt > 0 Then
2205                    TimerReply.Interval = SettingDialog.ReplyPeriodInt * 1000
2206                    TimerReply.Enabled = True
2207                Else
2208                    TimerReply.Interval = 6000000
2209                    TimerReply.Enabled = False
2210                End If
2211                If SettingDialog.DMPeriodInt > 0 Then
2212                    TimerDM.Interval = SettingDialog.DMPeriodInt * 1000
2213                    TimerDM.Enabled = True
2214                Else
2215                    TimerDM.Interval = 6000000
2216                    TimerDM.Enabled = False
2217                End If
2218                Twitter.NextThreshold = SettingDialog.NextPageThreshold
2219                Twitter.NextPages = SettingDialog.NextPagesInt
2220                If Twitter.UseAPI <> SettingDialog.UseAPI AndAlso Not _initial Then
2221                    chgUseApi = True
2222                End If
2223                Twitter.UseAPI = SettingDialog.UseAPI
2224                Twitter.CountApi = SettingDialog.CountApi
2225                Twitter.UsePostMethod = False
2226                Twitter.HubServer = SettingDialog.HubServer
2227                Twitter.TinyUrlResolve = SettingDialog.TinyUrlResolve
2228                Twitter.RestrictFavCheck = SettingDialog.RestrictFavCheck
2229
2230                Twitter.ProxyType = SettingDialog.ProxyType
2231                Twitter.ProxyAddress = SettingDialog.ProxyAddress
2232                Twitter.ProxyPort = SettingDialog.ProxyPort
2233                Twitter.ProxyUser = SettingDialog.ProxyUser
2234                Twitter.ProxyPassword = SettingDialog.ProxyPassword
2235
2236                If Not SettingDialog.UnreadManage Then
2237                    ReadedStripMenuItem.Enabled = False
2238                    UnreadStripMenuItem.Enabled = False
2239                    For Each myTab As TabPage In ListTab.TabPages
2240                        myTab.ImageIndex = -1
2241                    Next
2242                Else
2243                    ReadedStripMenuItem.Enabled = True
2244                    UnreadStripMenuItem.Enabled = True
2245                End If
2246                PlaySoundMenuItem.Checked = SettingDialog.PlaySound
2247                _fntUnread = SettingDialog.FontUnread
2248                _clUnread = SettingDialog.ColorUnread
2249                _fntReaded = SettingDialog.FontReaded
2250                _clReaded = SettingDialog.ColorReaded
2251                _clFav = SettingDialog.ColorFav
2252                _clOWL = SettingDialog.ColorOWL
2253                _fntDetail = SettingDialog.FontDetail
2254                _clSelf = SettingDialog.ColorSelf
2255                _clAtSelf = SettingDialog.ColorAtSelf
2256                _clTarget = SettingDialog.ColorTarget
2257                _clAtTarget = SettingDialog.ColorAtTarget
2258                _clAtFromTarget = SettingDialog.ColorAtFromTarget
2259                _clAtTo = SettingDialog.ColorAtTo
2260                _clInputBackcolor = SettingDialog.ColorInputBackcolor
2261                _clInputFont = SettingDialog.ColorInputFont
2262                _fntInputFont = SettingDialog.FontInputFont
2263                If StatusText.Focused Then StatusText.BackColor = _clInputBackcolor
2264                StatusText.Font = _fntInputFont
2265                StatusText.ForeColor = _clInputFont
2266                _brsForeColorUnread.Dispose()
2267                _brsForeColorReaded.Dispose()
2268                _brsForeColorFav.Dispose()
2269                _brsForeColorOWL.Dispose()
2270                _brsForeColorUnread = New SolidBrush(_clUnread)
2271                _brsForeColorReaded = New SolidBrush(_clReaded)
2272                _brsForeColorFav = New SolidBrush(_clFav)
2273                _brsForeColorOWL = New SolidBrush(_clOWL)
2274                _brsBackColorMine.Dispose()
2275                _brsBackColorAt.Dispose()
2276                _brsBackColorYou.Dispose()
2277                _brsBackColorAtYou.Dispose()
2278                _brsBackColorAtFromTarget.Dispose()
2279                _brsBackColorAtTo.Dispose()
2280                _brsBackColorMine = New SolidBrush(_clSelf)
2281                _brsBackColorAt = New SolidBrush(_clAtSelf)
2282                _brsBackColorYou = New SolidBrush(_clTarget)
2283                _brsBackColorAtYou = New SolidBrush(_clAtTarget)
2284                _brsBackColorAtFromTarget = New SolidBrush(_clAtFromTarget)
2285                _brsBackColorAtTo = New SolidBrush(_clAtTo)
2286                detailHtmlFormat = detailHtmlFormat1 + _fntDetail.Name + detailHtmlFormat2 + _fntDetail.Size.ToString() + detailHtmlFormat3
2287                _statuses.SetUnreadManage(SettingDialog.UnreadManage)
2288                For Each tb As TabPage In ListTab.TabPages
2289                    If _statuses.Tabs(tb.Text).UnreadCount = 0 Then
2290                        tb.ImageIndex = -1
2291                    Else
2292                        tb.ImageIndex = 0
2293                    End If
2294                    If tb.Controls IsNot Nothing AndAlso tb.Controls.Count > 0 Then
2295                        DirectCast(tb.Controls(0), DetailsListView).Font = _fntReaded
2296                    End If
2297                Next
2298
2299                SetMainWindowTitle()
2300                SetNotifyIconText()
2301
2302                _itemCache = Nothing
2303                _postCache = Nothing
2304                _curList.Refresh()
2305            End SyncLock
2306        End If
2307
2308        Me.TopMost = SettingDialog.AlwaysTop
2309        SaveConfigsAll()
2310
2311        If chgUseApi Then doGetFollowersMenu(False) 'API使用を切り替えたら取り直し
2312    End Sub
2313
2314    Private Sub PostBrowser_Navigated(ByVal sender As Object, ByVal e As System.Windows.Forms.WebBrowserNavigatedEventArgs) Handles PostBrowser.Navigated
2315        If e.Url.AbsoluteUri <> "about:blank" Then
2316            DispSelectedPost()
2317            OpenUriAsync(e.Url.AbsoluteUri)
2318        End If
2319    End Sub
2320
2321    Private Sub PostBrowser_Navigating(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserNavigatingEventArgs) Handles PostBrowser.Navigating
2322        If e.Url.Scheme = "data" Then
2323            StatusLabelUrl.Text = PostBrowser.StatusText.Replace("&", "&&")
2324        ElseIf e.Url.AbsoluteUri <> "about:blank" Then
2325            e.Cancel = True
2326            OpenUriAsync(e.Url.AbsoluteUri)
2327        End If
2328    End Sub
2329
2330    Private Function AddNewTab(ByVal tabName As String, ByVal startup As Boolean) As Boolean
2331        '重複チェック
2332        For Each tb As TabPage In ListTab.TabPages
2333            If tb.Text = tabName Then Return False
2334        Next
2335
2336        '新規タブ名チェック
2337        If tabName = My.Resources.AddNewTabText1 Then Return False
2338
2339        'Dim myTab As New TabStructure()
2340
2341        Dim _tabPage As TabPage = New TabPage
2342        Dim _listCustom As DetailsListView = New DetailsListView
2343        Dim _colHd1 As ColumnHeader = New ColumnHeader()  'アイコン
2344        Dim _colHd2 As ColumnHeader = New ColumnHeader()   'ニックネーム
2345        Dim _colHd3 As ColumnHeader = New ColumnHeader()   '本文
2346        Dim _colHd4 As ColumnHeader = New ColumnHeader()   '日付
2347        Dim _colHd5 As ColumnHeader = New ColumnHeader()   'ユーザID
2348        Dim _colHd6 As ColumnHeader = New ColumnHeader()   '未読
2349        Dim _colHd7 As ColumnHeader = New ColumnHeader()   'マーク&プロテクト
2350        Dim _colHd8 As ColumnHeader = New ColumnHeader()   'ソース
2351        'If Not _iconCol Then
2352        '_colHd2 = New ColumnHeader()
2353        '_colHd3 = New ColumnHeader()
2354        '_colHd4 = New ColumnHeader()
2355        '_colHd5 = New ColumnHeader()
2356        '_colHd6 = New ColumnHeader()
2357        '_colHd7 = New ColumnHeader()
2358        '_colHd8 = New ColumnHeader()
2359        '_colHd9 = New ColumnHeader()
2360        'End If
2361
2362        'If Not startup Then _section.ListElement.Add(New ListElement(tabName))
2363
2364        Dim cnt As Integer = ListTab.TabPages.Count
2365
2366        Me.SplitContainer1.Panel1.SuspendLayout()
2367        Me.SplitContainer1.Panel2.SuspendLayout()
2368        Me.SplitContainer1.SuspendLayout()
2369        Me.ListTab.SuspendLayout()
2370        Me.SuspendLayout()
2371
2372        _tabPage.SuspendLayout()
2373
2374        Me.ListTab.Controls.Add(_tabPage)
2375
2376        _tabPage.Controls.Add(_listCustom)
2377        _tabPage.Location = New Point(4, 4)
2378        _tabPage.Name = "CTab" + cnt.ToString()
2379        _tabPage.Size = New Size(380, 260)
2380        _tabPage.TabIndex = 2 + cnt
2381        _tabPage.Text = tabName
2382        _tabPage.UseVisualStyleBackColor = True
2383
2384        _listCustom.AllowColumnReorder = True
2385        If Not _iconCol Then
2386            _listCustom.Columns.AddRange(New ColumnHeader() {_colHd1, _colHd2, _colHd3, _colHd4, _colHd5, _colHd6, _colHd7, _colHd8})
2387        Else
2388            _listCustom.Columns.AddRange(New ColumnHeader() {_colHd1, _colHd3})
2389        End If
2390        _listCustom.ContextMenuStrip = Me.ContextMenuStrip2
2391        _listCustom.Dock = DockStyle.Fill
2392        _listCustom.FullRowSelect = True
2393        _listCustom.HideSelection = False
2394        _listCustom.Location = New Point(0, 0)
2395        _listCustom.Margin = New Padding(0)
2396        _listCustom.Name = "CList" + Environment.TickCount.ToString()
2397        _listCustom.ShowItemToolTips = True
2398        _listCustom.Size = New Size(380, 260)
2399        _listCustom.TabIndex = 4                                   'これ大丈夫?
2400        _listCustom.UseCompatibleStateImageBehavior = False
2401        _listCustom.View = View.Details
2402        _listCustom.OwnerDraw = True
2403        _listCustom.VirtualMode = True
2404        _listCustom.Font = _fntReaded
2405
2406        AddHandler _listCustom.SelectedIndexChanged, AddressOf MyList_SelectedIndexChanged
2407        AddHandler _listCustom.MouseDoubleClick, AddressOf MyList_MouseDoubleClick
2408        AddHandler _listCustom.ColumnClick, AddressOf MyList_ColumnClick
2409        AddHandler _listCustom.DrawColumnHeader, AddressOf MyList_DrawColumnHeader
2410
2411        Select Case _iconSz
2412            Case 26, 48
2413                AddHandler _listCustom.DrawItem, AddressOf MyList_DrawItem
2414            Case Else
2415                AddHandler _listCustom.DrawItem, AddressOf MyList_DrawItemDefault
2416        End Select
2417
2418        AddHandler _listCustom.Scrolled, AddressOf Mylist_Scrolled
2419        AddHandler _listCustom.MouseClick, AddressOf MyList_MouseClick
2420        AddHandler _listCustom.ColumnReordered, AddressOf MyList_ColumnReordered
2421        AddHandler _listCustom.ColumnWidthChanged, AddressOf MyList_ColumnWidthChanged
2422        AddHandler _listCustom.CacheVirtualItems, AddressOf MyList_CacheVirtualItems
2423        AddHandler _listCustom.RetrieveVirtualItem, AddressOf MyList_RetrieveVirtualItem
2424        AddHandler _listCustom.DrawSubItem, AddressOf MyList_DrawSubItem
2425
2426        _colHd1.Text = ""
2427        _colHd1.Width = 48
2428        'If Not _iconCol Then
2429        _colHd2.Text = My.Resources.AddNewTabText2
2430        _colHd2.Width = 80
2431        _colHd3.Text = My.Resources.AddNewTabText3
2432        _colHd3.Width = 300
2433        If SettingDialog.UseAPI Then
2434            _colHd4.Text = My.Resources.AddNewTabText4_2
2435        Else
2436            _colHd4.Text = My.Resources.AddNewTabText4
2437        End If
2438        _colHd4.Width = 50
2439        _colHd5.Text = My.Resources.AddNewTabText5
2440        _colHd5.Width = 50
2441        _colHd6.Text = ""
2442        _colHd6.Width = 16
2443        _colHd7.Text = ""
2444        _colHd7.Width = 16
2445        _colHd8.Text = "Source"
2446        _colHd8.Width = 50
2447        'End If
2448
2449        If Not IsDefaultTab(tabName) Then
2450            TabDialog.AddTab(tabName)
2451        End If
2452
2453        _listCustom.SmallImageList = TIconSmallList
2454        '_listCustom.ListViewItemSorter = listViewItemSorter
2455        Dim dispOrder(7) As Integer
2456        If Not startup Then
2457            For i As Integer = 0 To _curList.Columns.Count - 1
2458                For j As Integer = 0 To _curList.Columns.Count - 1
2459                    If _curList.Columns(j).DisplayIndex = i Then
2460                        dispOrder(i) = j
2461                        Exit For
2462                    End If
2463                Next
2464            Next
2465            For i As Integer = 0 To _curList.Columns.Count - 1
2466                _listCustom.Columns(i).Width = _curList.Columns(i).Width
2467                _listCustom.Columns(dispOrder(i)).DisplayIndex = i
2468            Next
2469        Else
2470            If _iconCol Then
2471                _listCustom.Columns(0).Width = _cfgLocal.Width1
2472                _listCustom.Columns(1).Width = _cfgLocal.Width3
2473                _listCustom.Columns(0).DisplayIndex = 0
2474                _listCustom.Columns(1).DisplayIndex = 1
2475            Else
2476                For i As Integer = 0 To 7
2477                    If _cfgLocal.DisplayIndex1 = i Then
2478                        dispOrder(i) = 0
2479                    ElseIf _cfgLocal.DisplayIndex2 = i Then
2480                        dispOrder(i) = 1
2481                    ElseIf _cfgLocal.DisplayIndex3 = i Then
2482                        dispOrder(i) = 2
2483                    ElseIf _cfgLocal.DisplayIndex4 = i Then
2484                        dispOrder(i) = 3
2485                    ElseIf _cfgLocal.DisplayIndex5 = i Then
2486                        dispOrder(i) = 4
2487                    ElseIf _cfgLocal.DisplayIndex6 = i Then
2488                        dispOrder(i) = 5
2489                    ElseIf _cfgLocal.DisplayIndex7 = i Then
2490                        dispOrder(i) = 6
2491                    ElseIf _cfgLocal.DisplayIndex8 = i Then
2492                        dispOrder(i) = 7
2493                    End If
2494                Next
2495                _listCustom.Columns(0).Width = _cfgLocal.Width1
2496                _listCustom.Columns(1).Width = _cfgLocal.Width2
2497                _listCustom.Columns(2).Width = _cfgLocal.Width3
2498                _listCustom.Columns(3).Width = _cfgLocal.Width4
2499                _listCustom.Columns(4).Width = _cfgLocal.Width5
2500                _listCustom.Columns(5).Width = _cfgLocal.Width6
2501                _listCustom.Columns(6).Width = _cfgLocal.Width7
2502                _listCustom.Columns(7).Width = _cfgLocal.Width8
2503                For i As Integer = 0 To 7
2504                    _listCustom.Columns(dispOrder(i)).DisplayIndex = i
2505                Next
2506            End If
2507        End If
2508
2509        _tabPage.ResumeLayout(False)
2510
2511        Me.SplitContainer1.Panel1.ResumeLayout(False)
2512        Me.SplitContainer1.Panel2.ResumeLayout(False)
2513        Me.SplitContainer1.ResumeLayout(False)
2514        Me.ListTab.ResumeLayout(False)
2515        Me.ResumeLayout(False)
2516        Me.PerformLayout()
2517        Return True
2518    End Function
2519
2520    Private Sub RemoveSpecifiedTab(ByVal TabName As String)
2521        Dim idx As Integer = 0
2522        For idx = 0 To ListTab.TabPages.Count - 1
2523            If ListTab.TabPages(idx).Text = TabName Then Exit For
2524        Next
2525
2526        If IsDefaultTab(TabName) Then Exit Sub
2527
2528        Dim tmp As String = String.Format(My.Resources.RemoveSpecifiedTabText1, Environment.NewLine)
2529        If MessageBox.Show(tmp, My.Resources.RemoveSpecifiedTabText2, _
2530                         MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
2531            Exit Sub
2532        End If
2533
2534        SetListProperty()   '他のタブに列幅等を反映
2535
2536        'オブジェクトインスタンスの削除
2537        Me.SplitContainer1.Panel1.SuspendLayout()
2538        Me.SplitContainer1.Panel2.SuspendLayout()
2539        Me.SplitContainer1.SuspendLayout()
2540        Me.ListTab.SuspendLayout()
2541        Me.SuspendLayout()
2542
2543        Dim _tabPage As TabPage = ListTab.TabPages(idx)
2544        Dim _listCustom As DetailsListView = DirectCast(_tabPage.Controls(0), DetailsListView)
2545
2546        _tabPage.SuspendLayout()
2547
2548        Me.ListTab.Controls.Remove(_tabPage)
2549        _tabPage.Controls.Remove(_listCustom)
2550        _listCustom.Columns.Clear()
2551        _listCustom.ContextMenuStrip = Nothing
2552
2553        RemoveHandler _listCustom.SelectedIndexChanged, AddressOf MyList_SelectedIndexChanged
2554        RemoveHandler _listCustom.MouseDoubleClick, AddressOf MyList_MouseDoubleClick
2555        RemoveHandler _listCustom.ColumnClick, AddressOf MyList_ColumnClick
2556        RemoveHandler _listCustom.DrawColumnHeader, AddressOf MyList_DrawColumnHeader
2557
2558        Select Case _iconSz
2559            Case 26, 48
2560                RemoveHandler _listCustom.DrawItem, AddressOf MyList_DrawItem
2561            Case Else
2562                RemoveHandler _listCustom.DrawItem, AddressOf MyList_DrawItemDefault
2563        End Select
2564
2565        RemoveHandler _listCustom.Scrolled, AddressOf Mylist_Scrolled
2566        RemoveHandler _listCustom.MouseClick, AddressOf MyList_MouseClick
2567        RemoveHandler _listCustom.ColumnReordered, AddressOf MyList_ColumnReordered
2568        RemoveHandler _listCustom.ColumnWidthChanged, AddressOf MyList_ColumnWidthChanged
2569        RemoveHandler _listCustom.CacheVirtualItems, AddressOf MyList_CacheVirtualItems
2570        RemoveHandler _listCustom.RetrieveVirtualItem, AddressOf MyList_RetrieveVirtualItem
2571        RemoveHandler _listCustom.DrawSubItem, AddressOf MyList_DrawSubItem
2572
2573        TabDialog.RemoveTab(TabName)
2574
2575        _listCustom.SmallImageList = Nothing
2576        _listCustom.ListViewItemSorter = Nothing
2577
2578        'キャッシュのクリア
2579        If _curTab.Equals(_tabPage) Then
2580            _curTab = Nothing
2581            _curItemIndex = -1
2582            _curList = Nothing
2583            _curPost = Nothing
2584        End If
2585        _itemCache = Nothing
2586        _itemCacheIndex = -1
2587        _postCache = Nothing
2588
2589        _tabPage.ResumeLayout(False)
2590
2591        Me.SplitContainer1.Panel1.ResumeLayout(False)
2592        Me.SplitContainer1.Panel2.ResumeLayout(False)
2593        Me.SplitContainer1.ResumeLayout(False)
2594        Me.ListTab.ResumeLayout(False)
2595        Me.ResumeLayout(False)
2596        Me.PerformLayout()
2597
2598        _tabPage.Dispose()
2599        _listCustom.Dispose()
2600        _statuses.RemoveTab(TabName)
2601
2602        SaveConfigsCommon()
2603        SaveConfigsTab()
2604
2605        For Each tp As TabPage In ListTab.TabPages
2606            Dim lst As DetailsListView = DirectCast(tp.Controls(0), DetailsListView)
2607            If lst.VirtualListSize <> _statuses.Tabs(tp.Text).AllCount Then
2608                lst.VirtualListSize = _statuses.Tabs(tp.Text).AllCount
2609            End If
2610        Next
2611    End Sub
2612
2613    Private Sub ListTab_Deselected(ByVal sender As Object, ByVal e As System.Windows.Forms.TabControlEventArgs) Handles ListTab.Deselected
2614        _itemCache = Nothing
2615        _itemCacheIndex = -1
2616        _postCache = Nothing
2617    End Sub
2618
2619    Private Sub ListTab_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseMove
2620        'タブのD&D
2621        Dim cpos As New Point(e.X, e.Y)
2622
2623        If e.Button = Windows.Forms.MouseButtons.Left AndAlso _tabDrag Then
2624            Dim tn As String = ""
2625            For i As Integer = 0 To ListTab.TabPages.Count - 1
2626                Dim rect As Rectangle = ListTab.GetTabRect(i)
2627                If rect.Left <= cpos.X AndAlso cpos.X <= rect.Right AndAlso _
2628                   rect.Top <= cpos.Y AndAlso cpos.Y <= rect.Bottom Then
2629                    tn = ListTab.TabPages(i).Text
2630                    Exit For
2631                End If
2632            Next
2633
2634            If tn = "" Then Exit Sub
2635
2636            For Each tb As TabPage In ListTab.TabPages
2637                If tb.Text = tn Then
2638                    ListTab.DoDragDrop(tb, DragDropEffects.All)
2639                    Exit For
2640                End If
2641            Next
2642        Else
2643            _tabDrag = False
2644        End If
2645
2646        For i As Integer = 0 To ListTab.TabPages.Count - 1
2647            Dim rect As Rectangle = ListTab.GetTabRect(i)
2648            If rect.Left <= cpos.X And cpos.X <= rect.Right And _
2649               rect.Top <= cpos.Y And cpos.Y <= rect.Bottom Then
2650                _rclickTabName = ListTab.TabPages(i).Text
2651                Exit For
2652            End If
2653        Next
2654    End Sub
2655
2656    Private Sub ListTab_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListTab.SelectedIndexChanged
2657        '_curList.Refresh()
2658        DispSelectedPost()
2659        SetMainWindowTitle()
2660        SetStatusLabel()
2661    End Sub
2662
2663    Private Sub SetListProperty()
2664        '削除などで見つからない場合は処理せず
2665        If _curList Is Nothing Then Exit Sub
2666
2667        Dim dispOrder(_curList.Columns.Count - 1) As Integer
2668        For i As Integer = 0 To _curList.Columns.Count - 1
2669            For j As Integer = 0 To _curList.Columns.Count - 1
2670                If _curList.Columns(j).DisplayIndex = i Then
2671                    dispOrder(i) = j
2672                    Exit For
2673                End If
2674            Next
2675        Next
2676
2677        '列幅、列並びを他のタブに設定
2678        For Each tb As TabPage In ListTab.TabPages
2679            If Not tb.Equals(_curTab) Then
2680                Dim lst As DetailsListView = DirectCast(tb.Controls(0), DetailsListView)
2681                For i As Integer = 0 To lst.Columns.Count - 1
2682                    lst.Columns(dispOrder(i)).DisplayIndex = i
2683                    lst.Columns(i).Width = _curList.Columns(i).Width
2684                Next
2685            End If
2686        Next
2687    End Sub
2688
2689    Private Sub PostBrowser_StatusTextChanged(ByVal sender As Object, ByVal e As EventArgs) Handles PostBrowser.StatusTextChanged
2690        If PostBrowser.StatusText.StartsWith("http") OrElse PostBrowser.StatusText.StartsWith("ftp") _
2691                OrElse PostBrowser.StatusText.StartsWith("data") Then
2692            StatusLabelUrl.Text = PostBrowser.StatusText.Replace("&", "&&")
2693            ToolStripMenuItem4.Enabled = True
2694        Else
2695            ToolStripMenuItem4.Enabled = False
2696        End If
2697        If PostBrowser.StatusText = "" Then
2698            SetStatusLabel()
2699        End If
2700    End Sub
2701
2702    Private Sub StatusText_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles StatusText.KeyUp
2703        'スペースキーで未読ジャンプ
2704        If Not e.Alt AndAlso Not e.Control AndAlso Not e.Shift Then
2705            If e.KeyCode = Keys.Space OrElse e.KeyCode = Keys.ProcessKey Then
2706                If StatusText.Text = " " OrElse StatusText.Text = " " Then
2707                    e.Handled = True
2708                    StatusText.Text = ""
2709                    JumpUnreadMenuItem_Click(Nothing, Nothing)
2710                End If
2711            End If
2712        End If
2713    End Sub
2714
2715    Private Sub StatusText_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusText.TextChanged
2716        '文字数カウント
2717        Dim pLen As Integer = 140 - StatusText.Text.Length
2718        lblLen.Text = pLen.ToString()
2719        If pLen < 0 Then
2720            StatusText.ForeColor = Color.Red
2721        Else
2722            StatusText.ForeColor = _clInputFont
2723        End If
2724    End Sub
2725
2726    Private Sub MyList_CacheVirtualItems(ByVal sender As System.Object, ByVal e As System.Windows.Forms.CacheVirtualItemsEventArgs)
2727        If _itemCache IsNot Nothing AndAlso _
2728           e.StartIndex >= _itemCacheIndex AndAlso _
2729           e.EndIndex < _itemCacheIndex + _itemCache.Length AndAlso _
2730           _curList.Equals(sender) Then
2731            'If the newly requested cache is a subset of the old cache,
2732            'no need to rebuild everything, so do nothing.
2733            Return
2734        End If
2735
2736        'Now we need to rebuild the cache.
2737        If _curList.Equals(sender) Then CreateCache(e.StartIndex, e.EndIndex)
2738    End Sub
2739
2740    Private Sub MyList_RetrieveVirtualItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.RetrieveVirtualItemEventArgs)
2741        If _itemCache IsNot Nothing AndAlso e.ItemIndex >= _itemCacheIndex AndAlso e.ItemIndex < _itemCacheIndex + _itemCache.Length AndAlso _curList.Equals(sender) Then
2742            'A cache hit, so get the ListViewItem from the cache instead of making a new one.
2743            e.Item = _itemCache(e.ItemIndex - _itemCacheIndex)
2744        Else
2745            'A cache miss, so create a new ListViewItem and pass it back.
2746            Dim tb As TabPage = DirectCast(DirectCast(sender, Tween.TweenCustomControl.DetailsListView).Parent, TabPage)
2747            Try
2748                e.Item = CreateItem(tb, _
2749                                    _statuses.Item(tb.Text, e.ItemIndex), _
2750                                    e.ItemIndex)
2751            Catch ex As Exception
2752                '不正な要求に対する間に合わせの応答
2753                Dim sitem() As String = {"", "", "", "", "", "", "", ""}
2754                e.Item = New ListViewItem(sitem, -1)
2755            End Try
2756        End If
2757    End Sub
2758
2759    Private Sub CreateCache(ByVal StartIndex As Integer, ByVal EndIndex As Integer)
2760        Try
2761            'キャッシュ要求(要求範囲±30を作成)
2762            StartIndex -= 30
2763            If StartIndex < 0 Then StartIndex = 0
2764            EndIndex += 30
2765            If EndIndex >= _statuses.Tabs(_curTab.Text).AllCount Then EndIndex = _statuses.Tabs(_curTab.Text).AllCount - 1
2766            _postCache = _statuses.Item(_curTab.Text, StartIndex, EndIndex) '配列で取得
2767            _itemCacheIndex = StartIndex
2768
2769            _itemCache = New ListViewItem(_postCache.Length - 1) {}
2770            For i As Integer = 0 To _postCache.Length - 1
2771                _itemCache(i) = CreateItem(_curTab, _postCache(i), StartIndex + i)
2772            Next i
2773        Catch ex As Exception
2774            'キャッシュ要求が実データとずれるため(イベントの遅延?)
2775            _postCache = Nothing
2776            _itemCache = Nothing
2777        End Try
2778    End Sub
2779
2780    Private Function CreateItem(ByVal Tab As TabPage, ByVal Post As PostClass, ByVal Index As Integer) As ListViewItem
2781        Dim mk As String = ""
2782        If Post.IsMark Then mk += "♪"
2783        If Post.IsProtect Then mk += "Ю"
2784        Dim sitem() As String = {"", Post.Nickname, Post.Data, Post.PDate.ToString(SettingDialog.DateTimeFormat), Post.Name, "", mk, Post.Source}
2785        Dim itm As ListViewItem = New ListViewItem(sitem, Post.ImageIndex)
2786        Dim read As Boolean = Post.IsRead
2787        '未読管理していなかったら既読として扱う
2788        If Not _statuses.Tabs(Tab.Text).UnreadManage OrElse _
2789           Not SettingDialog.UnreadManage Then read = True
2790        ChangeItemStyleRead(read, itm, Post, Nothing)
2791        If Tab.Equals(_curTab) Then ColorizeList(itm, Index)
2792        Return itm
2793    End Function
2794
2795    Private Sub MyList_DrawColumnHeader(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs)
2796        e.DrawDefault = True
2797    End Sub
2798
2799    Private Sub MyList_DrawItemDefault(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawListViewItemEventArgs)
2800        e.DrawDefault = True
2801    End Sub
2802
2803    Private Sub MyList_DrawItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawListViewItemEventArgs)
2804        'アイコンサイズ26,48はオーナードロー(DrawSubItem発生させる)
2805        If e.State = 0 Then Exit Sub
2806        e.DrawDefault = False
2807        If Not e.Item.Selected Then     'e.ItemStateでうまく判定できない???
2808            Dim brs2 As SolidBrush = Nothing
2809            Select Case e.Item.BackColor
2810                Case _clSelf
2811                    brs2 = _brsBackColorMine
2812                Case _clAtSelf
2813                    brs2 = _brsBackColorAt
2814                Case _clTarget
2815                    brs2 = _brsBackColorYou
2816                Case _clAtTarget
2817                    brs2 = _brsBackColorAtYou
2818                Case _clAtFromTarget
2819                    brs2 = _brsBackColorAtFromTarget
2820                Case _clAtTo
2821                    brs2 = _brsBackColorAtTo
2822                Case Else
2823                    brs2 = _brsBackColorNone
2824            End Select
2825            e.Graphics.FillRectangle(brs2, e.Bounds)
2826        Else
2827            '選択中の行
2828            If DirectCast(sender, Windows.Forms.Control).Focused Then
2829                e.Graphics.FillRectangle(_brsHighLight, e.Bounds)
2830            Else
2831                e.Graphics.FillRectangle(_brsDeactiveSelection, e.Bounds)
2832            End If
2833        End If
2834        If (e.State And ListViewItemStates.Focused) = ListViewItemStates.Focused Then e.DrawFocusRectangle()
2835    End Sub
2836
2837    Private Sub MyList_DrawSubItem(ByVal sender As Object, ByVal e As DrawListViewSubItemEventArgs)
2838        If e.ItemState = 0 Then Exit Sub
2839        If e.ColumnIndex > 0 Then
2840            Dim rct As RectangleF = e.Bounds
2841            rct.Width = e.Header.Width
2842            'アイコン以外の列
2843            If Not e.Item.Selected Then     'e.ItemStateでうまく判定できない???
2844                '選択されていない行
2845                '文字色
2846                Dim brs As SolidBrush = Nothing
2847                Select Case e.Item.ForeColor
2848                    Case _clUnread
2849                        brs = _brsForeColorUnread
2850                    Case _clReaded
2851                        brs = _brsForeColorReaded
2852                    Case _clFav
2853                        brs = _brsForeColorFav
2854                    Case _clOWL
2855                        brs = _brsForeColorOWL
2856                    Case Else
2857                        brs = New SolidBrush(e.Item.ForeColor)
2858                End Select
2859                If rct.Width > 0 Then
2860                    If _iconCol Then
2861                        e.Graphics.DrawString(e.Item.SubItems(4).Text + "/" + e.Item.SubItems(1).Text + " (" + e.Item.SubItems(3).Text + ") <" + e.Item.SubItems(5).Text + e.Item.SubItems(6).Text + "> from " + e.Item.SubItems(7).Text + System.Environment.NewLine + e.Item.SubItems(2).Text, e.Item.Font, brs, rct, sf)
2862                    Else
2863                        e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, brs, rct, sf)
2864                    End If
2865                End If
2866            Else
2867                If rct.Width > 0 Then
2868                    '選択中の行
2869                    If DirectCast(sender, Windows.Forms.Control).Focused Then
2870                        If _iconCol Then
2871                            e.Graphics.DrawString(e.Item.SubItems(4).Text + "/" + e.Item.SubItems(1).Text + " (" + e.Item.SubItems(3).Text + ") <" + e.Item.SubItems(5).Text + e.Item.SubItems(6).Text + "> from " + e.Item.SubItems(7).Text + System.Environment.NewLine + e.Item.SubItems(2).Text, e.Item.Font, _brsHighLightText, rct, sf)
2872                        Else
2873                            e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, _brsHighLightText, rct, sf)
2874                        End If
2875                    Else
2876                        If _iconCol Then
2877                            e.Graphics.DrawString(e.Item.SubItems(4).Text + "/" + e.Item.SubItems(1).Text + " (" + e.Item.SubItems(3).Text + ") <" + e.Item.SubItems(5).Text + e.Item.SubItems(6).Text + "> from " + e.Item.SubItems(7).Text + System.Environment.NewLine + e.Item.SubItems(2).Text, e.Item.Font, _brsForeColorUnread, rct, sf)
2878                        Else
2879                            e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, _brsForeColorUnread, rct, sf)
2880                        End If
2881                    End If
2882                End If
2883            End If
2884        Else
2885            'アイコン列はデフォルト描画
2886            e.DrawDefault = True
2887        End If
2888    End Sub
2889
2890    Private Sub DoTabSearch(ByVal _word As String, _
2891                            ByVal CaseSensitive As Boolean, _
2892                            ByVal UseRegex As Boolean, _
2893                            ByVal SType As SEARCHTYPE)
2894        'Dim myList As DetailsListView = DirectCast(ListTab.SelectedTab.Controls(0), DetailsListView)
2895        Dim cidx As Integer = 0
2896        Dim fnd As Boolean = False
2897        Dim toIdx As Integer
2898        Dim stp As Integer = 1
2899
2900        If _curList.VirtualListSize = 0 Then
2901            MessageBox.Show(My.Resources.DoTabSearchText2, My.Resources.DoTabSearchText3, MessageBoxButtons.OK, MessageBoxIcon.Information)
2902        End If
2903
2904        If _curList.SelectedIndices.Count > 0 Then
2905            cidx = _curList.SelectedIndices(0)
2906        End If
2907        toIdx = _curList.VirtualListSize - 1
2908
2909        Select Case SType
2910            Case SEARCHTYPE.DialogSearch    'ダイアログからの検索
2911                If _curList.SelectedIndices.Count > 0 Then
2912                    cidx = _curList.SelectedIndices(0)
2913                Else
2914                    cidx = 0
2915                End If
2916            Case SEARCHTYPE.NextSearch      '次を検索
2917                If _curList.SelectedIndices.Count > 0 Then
2918                    cidx = _curList.SelectedIndices(0) + 1
2919                    If cidx > toIdx Then cidx = toIdx
2920                Else
2921                    cidx = 0
2922                End If
2923            Case SEARCHTYPE.PrevSearch      '前を検索
2924                If _curList.SelectedIndices.Count > 0 Then
2925                    cidx = _curList.SelectedIndices(0) - 1
2926                    If cidx < 0 Then cidx = 0
2927                Else
2928                    cidx = toIdx
2929                End If
2930                toIdx = 0
2931                stp = -1
2932        End Select
2933
2934        Dim regOpt As RegexOptions = RegexOptions.None
2935        Dim fndOpt As StringComparison = StringComparison.Ordinal
2936        If Not CaseSensitive Then
2937            regOpt = RegexOptions.IgnoreCase
2938            fndOpt = StringComparison.OrdinalIgnoreCase
2939        End If
2940        Try
2941RETRY:
2942            If UseRegex Then
2943                ' 正規表現検索
2944                Dim _search As Regex
2945                Try
2946                    _search = New Regex(_word)
2947                    For idx As Integer = cidx To toIdx Step stp
2948                        Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
2949                        If _search.IsMatch(post.Nickname, regOpt) _
2950                            OrElse _search.IsMatch(post.Data, regOpt) _
2951                            OrElse _search.IsMatch(post.Name, regOpt) _
2952                        Then
2953                            SelectListItem(_curList, idx)
2954                            _curList.EnsureVisible(idx)
2955                            Exit Sub
2956                        End If
2957                    Next
2958                Catch ex As ArgumentException
2959                    MsgBox(My.Resources.DoTabSearchText1, MsgBoxStyle.Critical)
2960                    Exit Sub
2961                End Try
2962            Else
2963                ' 通常検索
2964                For idx As Integer = cidx To toIdx Step stp
2965                    Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
2966                    If post.Nickname.IndexOf(_word, fndOpt) > -1 _
2967                        OrElse post.Data.IndexOf(_word, fndOpt) > -1 _
2968                        OrElse post.Name.IndexOf(_word, fndOpt) > -1 _
2969                    Then
2970                        SelectListItem(_curList, idx)
2971                        _curList.EnsureVisible(idx)
2972                        Exit Sub
2973                    End If
2974                Next
2975            End If
2976
2977            If Not fnd Then
2978                Select Case SType
2979                    Case SEARCHTYPE.DialogSearch, SEARCHTYPE.NextSearch
2980                        toIdx = cidx
2981                        cidx = 0
2982                    Case SEARCHTYPE.PrevSearch
2983                        toIdx = cidx
2984                        cidx = _curList.Items.Count - 1
2985                End Select
2986                fnd = True
2987                GoTo RETRY
2988            End If
2989        Catch ex As ArgumentOutOfRangeException
2990
2991        End Try
2992        MessageBox.Show(My.Resources.DoTabSearchText2, My.Resources.DoTabSearchText3, MessageBoxButtons.OK, MessageBoxIcon.Information)
2993    End Sub
2994
2995    Private Sub MenuItemSubSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemSubSearch.Click
2996        '検索メニュー
2997        SearchDialog.Owner = Me
2998        If SearchDialog.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
2999            Me.TopMost = SettingDialog.AlwaysTop
3000            Exit Sub
3001        End If
3002        Me.TopMost = SettingDialog.AlwaysTop
3003
3004        If SearchDialog.SWord <> "" Then
3005            DoTabSearch(SearchDialog.SWord, _
3006                        SearchDialog.CheckCaseSensitive, _
3007                        SearchDialog.CheckRegex, _
3008                        SEARCHTYPE.DialogSearch)
3009        End If
3010    End Sub
3011
3012    Private Sub MenuItemSearchNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemSearchNext.Click
3013        '次を検索
3014        If SearchDialog.SWord = "" Then
3015            If SearchDialog.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
3016                Me.TopMost = SettingDialog.AlwaysTop
3017                Exit Sub
3018            End If
3019            Me.TopMost = SettingDialog.AlwaysTop
3020            If SearchDialog.SWord = "" Then Exit Sub
3021
3022            DoTabSearch(SearchDialog.SWord, _
3023                        SearchDialog.CheckCaseSensitive, _
3024                        SearchDialog.CheckRegex, _
3025                        SEARCHTYPE.DialogSearch)
3026        Else
3027            DoTabSearch(SearchDialog.SWord, _
3028                        SearchDialog.CheckCaseSensitive, _
3029                        SearchDialog.CheckRegex, _
3030                        SEARCHTYPE.NextSearch)
3031        End If
3032    End Sub
3033
3034    Private Sub MenuItemSearchPrev_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemSearchPrev.Click
3035        '前を検索
3036        If SearchDialog.SWord = "" Then
3037            If SearchDialog.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
3038                Me.TopMost = SettingDialog.AlwaysTop
3039                Exit Sub
3040            End If
3041            Me.TopMost = SettingDialog.AlwaysTop
3042            If SearchDialog.SWord = "" Then Exit Sub
3043        End If
3044
3045        DoTabSearch(SearchDialog.SWord, _
3046                    SearchDialog.CheckCaseSensitive, _
3047                    SearchDialog.CheckRegex, _
3048                    SEARCHTYPE.PrevSearch)
3049    End Sub
3050
3051    Private Sub AboutMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AboutMenuItem.Click
3052        TweenAboutBox.ShowDialog()
3053        Me.TopMost = SettingDialog.AlwaysTop
3054    End Sub
3055
3056    Private Sub JumpUnreadMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles JumpUnreadMenuItem.Click
3057        Dim bgnIdx As Integer = ListTab.TabPages.IndexOf(_curTab)
3058        Dim idx As Integer = -1
3059        Dim lst As DetailsListView = Nothing
3060
3061        '現在タブから最終タブまで探索
3062        For i As Integer = bgnIdx To ListTab.TabPages.Count - 1
3063            '未読Index取得
3064            idx = _statuses.GetOldestUnreadId(ListTab.TabPages(i).Text)
3065            If idx > -1 Then
3066                ListTab.SelectedIndex = i
3067                lst = DirectCast(ListTab.TabPages(i).Controls(0), DetailsListView)
3068                Exit For
3069            End If
3070        Next
3071
3072        '未読みつからず&現在タブが先頭ではなかったら、先頭タブから現在タブの手前まで探索
3073        If idx = -1 AndAlso bgnIdx > 0 Then
3074            For i As Integer = 0 To bgnIdx - 1
3075                idx = _statuses.GetOldestUnreadId(ListTab.TabPages(i).Text)
3076                If idx > -1 Then
3077                    ListTab.SelectedIndex = i
3078                    lst = DirectCast(ListTab.TabPages(i).Controls(0), DetailsListView)
3079                    Exit For
3080                End If
3081            Next
3082        End If
3083
3084        '全部調べたが未読見つからず→先頭タブの最新発言へ
3085        If idx = -1 Then
3086            ListTab.SelectedIndex = 0
3087            lst = DirectCast(ListTab.TabPages(0).Controls(0), DetailsListView)
3088            If _statuses.SortOrder = SortOrder.Ascending Then
3089                idx = lst.VirtualListSize - 1
3090            Else
3091                idx = 0
3092            End If
3093        End If
3094
3095        If lst.VirtualListSize > 0 AndAlso idx > -1 AndAlso lst.VirtualListSize > idx Then
3096            SelectListItem(lst, idx)
3097            If _statuses.SortMode = IdComparerClass.ComparerMode.Id Then
3098                If _statuses.SortOrder = SortOrder.Ascending AndAlso lst.Items(idx).Position.Y > lst.ClientSize.Height - _iconSz - 10 OrElse _
3099                   _statuses.SortOrder = SortOrder.Descending AndAlso lst.Items(idx).Position.Y < _iconSz + 10 Then
3100                    MoveTop()
3101                Else
3102                    lst.EnsureVisible(idx)
3103                End If
3104            Else
3105                lst.EnsureVisible(idx)
3106            End If
3107        End If
3108        lst.Focus()
3109    End Sub
3110
3111    Private Sub StatusOpenMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusOpenMenuItem.Click
3112        If _curList.SelectedIndices.Count > 0 Then
3113            Dim post As PostClass = _statuses.Item(_curTab.Text, _curList.SelectedIndices(0))
3114            OpenUriAsync("http://twitter.com/" + post.Name + "/statuses/" + post.Id.ToString)
3115        End If
3116    End Sub
3117
3118    Private Sub FavorareMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles FavorareMenuItem.Click
3119        If _curList.SelectedIndices.Count > 0 Then
3120            Dim post As PostClass = _statuses.Item(_curTab.Text, _curList.SelectedIndices(0))
3121            OpenUriAsync("http://favotter.matope.com/user.php?user=" + post.Name)
3122        End If
3123    End Sub
3124
3125    Private Sub VerUpMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles VerUpMenuItem.Click
3126        CheckNewVersion()
3127    End Sub
3128
3129    Private Sub RunTweenUp()
3130
3131        Dim pinfo As New ProcessStartInfo
3132        pinfo.UseShellExecute = True
3133        pinfo.WorkingDirectory = Application.StartupPath
3134        pinfo.FileName = Path.Combine(Application.StartupPath(), "TweenUp.exe")
3135        Try
3136            Process.Start(pinfo)
3137        Catch ex As Exception
3138            MsgBox("TweenUp.exeの実行に失敗しました。")
3139        End Try
3140    End Sub
3141
3142    Private Sub CheckNewVersion(Optional ByVal startup As Boolean = False)
3143        Dim retMsg As String = ""
3144        Dim strVer As String
3145        Dim forceUpdate As Boolean = My.Computer.Keyboard.ShiftKeyDown
3146
3147        Try
3148            retMsg = Twitter.GetVersionInfo()
3149        Catch ex As Exception
3150            StatusLabel.Text = My.Resources.CheckNewVersionText9
3151            If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText10, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
3152            Exit Sub
3153        End Try
3154        If retMsg.Length > 0 Then
3155            strVer = retMsg.Substring(0, 4)
3156            If strVer.CompareTo(My.Application.Info.Version.ToString.Replace(".", "")) > 0 Then
3157                Dim tmp As String = String.Format(My.Resources.CheckNewVersionText3, strVer)
3158                If dialogAsShieldicon.Show(tmp, My.Resources.CheckNewVersionText1, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
3159                    retMsg = Twitter.GetTweenBinary(strVer)
3160                    If retMsg.Length = 0 Then
3161                        retMsg = Twitter.GetTweenUpBinary()
3162                        If retMsg.Length = 0 Then
3163                            RunTweenUp()
3164                            'If startup Then
3165                            '    Application.Exit()
3166                            'Else
3167                            _endingFlag = True
3168                            Me.Close()
3169                            'End If
3170                            Exit Sub
3171                        Else
3172                            If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText4 + System.Environment.NewLine + retMsg, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
3173                        End If
3174                    Else
3175                        If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText5 + System.Environment.NewLine + retMsg, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
3176                    End If
3177                End If
3178            Else
3179                If forceUpdate Then
3180                    Dim tmp As String = String.Format(My.Resources.CheckNewVersionText6, strVer)
3181                    If dialogAsShieldicon.Show(tmp, My.Resources.CheckNewVersionText1, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
3182                        retMsg = Twitter.GetTweenBinary(strVer)
3183                        If retMsg.Length = 0 Then
3184                            retMsg = Twitter.GetTweenUpBinary()
3185                            If retMsg.Length = 0 Then
3186                                RunTweenUp()
3187                                'If startup Then
3188                                '    Application.Exit()
3189                                'Else
3190                                _endingFlag = True
3191                                Me.Close()
3192                                'End If
3193                                Exit Sub
3194                            Else
3195                                If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText4 + System.Environment.NewLine + retMsg, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
3196                            End If
3197                        Else
3198                            If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText5 + System.Environment.NewLine + retMsg, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
3199                        End If
3200                    End If
3201                ElseIf Not startup Then
3202                    MessageBox.Show(My.Resources.CheckNewVersionText7 + My.Application.Info.Version.ToString.Replace(".", "") + My.Resources.CheckNewVersionText8 + strVer, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Information)
3203                End If
3204            End If
3205        Else
3206            StatusLabel.Text = My.Resources.CheckNewVersionText9
3207            If Not startup Then MessageBox.Show(My.Resources.CheckNewVersionText10, My.Resources.CheckNewVersionText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
3208        End If
3209    End Sub
3210
3211    Private Sub TimerColorize_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerColorize.Tick
3212        If TimerColorize.Enabled = False Then Exit Sub
3213
3214        TimerColorize.Stop()
3215        TimerColorize.Enabled = False
3216        TimerColorize.Interval = 200
3217        DispSelectedPost()
3218        '件数関連の場合、タイトル即時書き換え
3219        If SettingDialog.DispLatestPost <> DispTitleEnum.None AndAlso _
3220           SettingDialog.DispLatestPost <> DispTitleEnum.Post AndAlso _
3221           SettingDialog.DispLatestPost <> DispTitleEnum.Ver Then
3222            SetMainWindowTitle()
3223        End If
3224        If Not StatusLabelUrl.Text.StartsWith("http") Then SetStatusLabel()
3225        For Each tb As TabPage In ListTab.TabPages
3226            If _statuses.Tabs(tb.Text).UnreadCount = 0 AndAlso tb.ImageIndex = 0 Then tb.ImageIndex = -1
3227        Next
3228    End Sub
3229
3230    Private Sub DispSelectedPost()
3231
3232        If _curList.SelectedIndices.Count = 0 OrElse _curPost Is Nothing Then Exit Sub
3233
3234        Dim dTxt As String = detailHtmlFormat + _curPost.OriginalData + detailHtmlFormat4
3235        If _curTab.Text = DEFAULTTAB.DM AndAlso _curPost.IsOwl Then
3236            NameLabel.Text = "DirectMessage To "
3237        ElseIf _curTab.Text = DEFAULTTAB.DM Then
3238            NameLabel.Text = "DirectMessage From "
3239        Else
3240            NameLabel.Text = ""
3241        End If
3242        NameLabel.Text += _curPost.Name + "/" + _curPost.Nickname
3243        'If UserPicture.Image IsNot Nothing Then UserPicture.Image.Dispose()
3244        If _curPost.ImageIndex > -1 Then
3245            UserPicture.Image = TIconDic(_curPost.ImageUrl)
3246        Else
3247            UserPicture.Image = Nothing
3248        End If
3249        'UserPicture.Refresh()
3250
3251        NameLabel.ForeColor = System.Drawing.SystemColors.ControlText
3252        DateTimeLabel.Text = _curPost.PDate.ToString()
3253        If _curPost.IsOwl AndAlso (SettingDialog.OneWayLove OrElse _curTab.Text = DEFAULTTAB.DM) Then NameLabel.ForeColor = _clOWL
3254        If _curPost.IsFav Then NameLabel.ForeColor = _clFav
3255
3256        If DumpPostClassToolStripMenuItem.Checked Then
3257            Dim sb As New StringBuilder(512)
3258
3259            sb.Append("-----Start PostClass Dump<br>")
3260            sb.AppendFormat("Data           : {0}<br>", _curPost.Data)
3261            sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.Data)
3262            sb.AppendFormat("Id             : {0}<br>", _curPost.Id.ToString)
3263            sb.AppendFormat("ImageIndex     : {0}<br>", _curPost.ImageIndex.ToString)
3264            sb.AppendFormat("ImageUrl       : {0}<br>", _curPost.ImageUrl)
3265            sb.AppendFormat("InReplyToId    : {0}<br>", _curPost.InReplyToId.ToString)
3266            sb.AppendFormat("InReplyToUser  : {0}<br>", _curPost.InReplyToUser)
3267            sb.AppendFormat("IsDM           : {0}<br>", _curPost.IsDm.ToString)
3268            sb.AppendFormat("IsFav          : {0}<br>", _curPost.IsFav.ToString)
3269            sb.AppendFormat("IsMark         : {0}<br>", _curPost.IsMark.ToString)
3270            sb.AppendFormat("IsMe           : {0}<br>", _curPost.IsMe.ToString)
3271            sb.AppendFormat("IsOwl          : {0}<br>", _curPost.IsOwl.ToString)
3272            sb.AppendFormat("IsProtect      : {0}<br>", _curPost.IsProtect.ToString)
3273            sb.AppendFormat("IsRead         : {0}<br>", _curPost.IsRead.ToString)
3274            sb.AppendFormat("IsReply        : {0}<br>", _curPost.IsReply.ToString)
3275
3276            For Each nm As String In _curPost.ReplyToList
3277                sb.AppendFormat("ReplyToList    : {0}<br>", nm)
3278            Next
3279
3280            sb.AppendFormat("Name           : {0}<br>", _curPost.Name)
3281            sb.AppendFormat("NickName       : {0}<br>", _curPost.Nickname)
3282            sb.AppendFormat("OriginalData   : {0}<br>", _curPost.OriginalData)
3283            sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.OriginalData)
3284            sb.AppendFormat("PDate          : {0}<br>", _curPost.PDate.ToString)
3285            sb.AppendFormat("Source         : {0}<br>", _curPost.Source)
3286            sb.Append("-----End PostClass Dump<br>")
3287
3288            PostBrowser.Visible = False
3289            PostBrowser.DocumentText = detailHtmlFormat + sb.ToString + detailHtmlFormat4
3290            PostBrowser.Visible = True
3291        ElseIf PostBrowser.DocumentText <> dTxt Then
3292            PostBrowser.Visible = False
3293            PostBrowser.DocumentText = dTxt
3294            PostBrowser.Visible = True
3295        End If
3296    End Sub
3297
3298    Private Sub MatomeMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MatomeMenuItem.Click
3299        OpenUriAsync("http://www5.atwiki.jp/tween/")
3300    End Sub
3301
3302    Private Sub OfficialMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OfficialMenuItem.Click
3303        OpenUriAsync("http://d.hatena.ne.jp/Kiri_Feather/20071121")
3304    End Sub
3305
3306    Private Sub DLPageMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DLPageMenuItem.Click
3307        OpenUriAsync("http://tween.sourceforge.jp/index.html")
3308    End Sub
3309
3310    Private Sub ListTab_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles ListTab.KeyDown
3311        If e.Modifiers = Keys.None Then
3312            ' ModifierKeyが押されていない場合
3313            If e.KeyCode = Keys.N OrElse e.KeyCode = Keys.Right Then
3314                e.Handled = True
3315                e.SuppressKeyPress = True
3316                GoRelPost(True)
3317                Exit Sub
3318            End If
3319            If e.KeyCode = Keys.P OrElse e.KeyCode = Keys.Left Then
3320                e.Handled = True
3321                e.SuppressKeyPress = True
3322                GoRelPost(False)
3323                Exit Sub
3324            End If
3325            If e.KeyCode = Keys.OemPeriod Then
3326                e.Handled = True
3327                e.SuppressKeyPress = True
3328                GoAnchor()
3329                Exit Sub
3330            End If
3331            _anchorFlag = False
3332            If e.KeyCode = Keys.Space OrElse e.KeyCode = Keys.ProcessKey Then
3333                e.Handled = True
3334                e.SuppressKeyPress = True
3335                JumpUnreadMenuItem_Click(Nothing, Nothing)
3336            End If
3337            If e.KeyCode = Keys.Enter OrElse e.KeyCode = Keys.Return Then
3338                e.Handled = True
3339                e.SuppressKeyPress = True
3340                MakeReplyOrDirectStatus()
3341            End If
3342            If e.KeyCode = Keys.L Then
3343                e.Handled = True
3344                e.SuppressKeyPress = True
3345                GoPost(True)
3346            End If
3347            If e.KeyCode = Keys.H Then
3348                e.Handled = True
3349                e.SuppressKeyPress = True
3350                GoPost(False)
3351            End If
3352            If e.KeyCode = Keys.Z Or e.KeyCode = Keys.Oemcomma Then
3353                e.Handled = True
3354                e.SuppressKeyPress = True
3355                MoveTop()
3356            End If
3357            If e.KeyCode = Keys.R Then
3358                e.Handled = True
3359                e.SuppressKeyPress = True
3360                DoRefresh()
3361            End If
3362            If e.KeyCode = Keys.S Then
3363                e.Handled = True
3364                e.SuppressKeyPress = True
3365                SendKeys.Send("^{PGDN}")
3366            End If
3367            If e.KeyCode = Keys.A Then
3368                e.Handled = True
3369                e.SuppressKeyPress = True
3370                SendKeys.Send("^{PGUP}")
3371            End If
3372        End If
3373        _anchorFlag = False
3374        If e.Control AndAlso Not e.Alt AndAlso Not e.Shift Then
3375            ' CTRLキーが押されている場合
3376            If e.KeyCode = Keys.Home OrElse e.KeyCode = Keys.End Then
3377                TimerColorize.Stop()
3378                TimerColorize.Start()
3379            End If
3380            If e.KeyCode = Keys.N Then SendKeys.Send("^{PGDN}")
3381            If e.KeyCode = Keys.P Then SendKeys.Send("^{PGUP}")
3382        End If
3383        If Not e.Control AndAlso e.Alt AndAlso Not e.Shift Then
3384            ' ALTキーが押されている場合
3385            ' 別タブの同じ書き込みへ(ALT+←/→)
3386            If e.KeyCode = Keys.Right Then
3387                e.Handled = True
3388                e.SuppressKeyPress = True
3389                GoSamePostToAnotherTab(False)
3390            End If
3391            If e.KeyCode = Keys.Left Then
3392                e.Handled = True
3393                e.SuppressKeyPress = True
3394                GoSamePostToAnotherTab(True)
3395            End If
3396        End If
3397        If e.Shift AndAlso Not e.Control AndAlso Not e.Alt Then
3398            ' SHIFTキーが押されている場合
3399            If e.KeyCode = Keys.H Then
3400                e.Handled = True
3401                e.SuppressKeyPress = True
3402                GoTopEnd(True)
3403            End If
3404            If e.KeyCode = Keys.L Then
3405                e.Handled = True
3406                e.SuppressKeyPress = True
3407                GoTopEnd(False)
3408            End If
3409            If e.KeyCode = Keys.M Then
3410                e.Handled = True
3411                e.SuppressKeyPress = True
3412                GoMiddle()
3413            End If
3414            If e.KeyCode = Keys.G Then
3415                e.Handled = True
3416                e.SuppressKeyPress = True
3417                GoLast()
3418            End If
3419            If e.KeyCode = Keys.Z Then
3420                e.Handled = True
3421                e.SuppressKeyPress = True
3422                MoveMiddle()
3423            End If
3424
3425            ' お気に入り前後ジャンプ(SHIFT+N←/P→)
3426            If e.KeyCode = Keys.N OrElse e.KeyCode = Keys.Right Then
3427                e.Handled = True
3428                e.SuppressKeyPress = True
3429                GoFav(True)
3430            End If
3431            If e.KeyCode = Keys.P OrElse e.KeyCode = Keys.Left Then
3432                e.Handled = True
3433                e.SuppressKeyPress = True
3434                GoFav(False)
3435            End If
3436
3437        End If
3438        If Not e.Alt Then
3439            If e.KeyCode = Keys.J Then
3440                e.Handled = True
3441                e.SuppressKeyPress = True
3442                SendKeys.Send("{DOWN}")
3443            End If
3444            If e.KeyCode = Keys.K Then
3445                e.Handled = True
3446                e.SuppressKeyPress = True
3447                SendKeys.Send("{UP}")
3448            End If
3449        End If
3450        If e.KeyCode = Keys.C Then
3451            Dim clstr As String = ""
3452            If e.Control AndAlso Not e.Alt AndAlso Not e.Shift Then
3453                e.Handled = True
3454                e.SuppressKeyPress = True
3455                CopyStot()
3456            End If
3457            If e.Control AndAlso e.Shift AndAlso Not e.Alt Then
3458                e.Handled = True
3459                e.SuppressKeyPress = True
3460                CopyIdUri()
3461            End If
3462        End If
3463    End Sub
3464
3465    Private Sub CopyStot()
3466        Dim clstr As String = ""
3467        Dim sb As New StringBuilder()
3468        For Each idx As Integer In _curList.SelectedIndices
3469            Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
3470            If post.IsProtect AndAlso SettingDialog.ProtectNotInclude Then Continue For
3471            sb.AppendFormat("{0}:{1} [http://twitter.com/{0}/statuses/{2}]{3}", post.Name, post.Data, post.Id, Environment.NewLine)
3472        Next
3473        If sb.Length > 0 Then
3474            clstr = sb.ToString()
3475            Clipboard.SetDataObject(clstr, False, 5, 100)
3476        End If
3477    End Sub
3478
3479    Private Sub CopyIdUri()
3480        Dim clstr As String = ""
3481        Dim sb As New StringBuilder()
3482        For Each idx As Integer In _curList.SelectedIndices
3483            Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
3484            sb.AppendFormat("http://twitter.com/{0}/statuses/{1}{2}", post.Name, post.Id, Environment.NewLine)
3485        Next
3486        If sb.Length > 0 Then
3487            clstr = sb.ToString()
3488            Clipboard.SetDataObject(clstr, False, 5, 100)
3489        End If
3490    End Sub
3491
3492    Private Sub GoFav(ByVal forward As Boolean)
3493        If _curList.VirtualListSize = 0 Then Exit Sub
3494        Dim fIdx As Integer = 0
3495        Dim toIdx As Integer = 0
3496        Dim stp As Integer = 1
3497
3498        If forward Then
3499            If _curList.SelectedIndices.Count = 0 Then
3500                fIdx = 0
3501            Else
3502                fIdx = _curList.SelectedIndices(0) + 1
3503                If fIdx > _curList.VirtualListSize - 1 Then Exit Sub
3504            End If
3505            toIdx = _curList.VirtualListSize - 1
3506            stp = 1
3507        Else
3508            If _curList.SelectedIndices.Count = 0 Then
3509                fIdx = _curList.VirtualListSize - 1
3510            Else
3511                fIdx = _curList.SelectedIndices(0) - 1
3512                If fIdx < 0 Then Exit Sub
3513            End If
3514            toIdx = 0
3515            stp = -1
3516        End If
3517
3518        For idx As Integer = fIdx To toIdx Step stp
3519            If _statuses.Item(_curTab.Text, idx).IsFav Then
3520                SelectListItem(_curList, idx)
3521                _curList.EnsureVisible(idx)
3522                Exit For
3523            End If
3524        Next
3525    End Sub
3526
3527    Private Sub GoSamePostToAnotherTab(ByVal left As Boolean)
3528        If _curList.VirtualListSize = 0 Then Exit Sub
3529        Dim fIdx As Integer = 0
3530        Dim toIdx As Integer = 0
3531        Dim stp As Integer = 1
3532        Dim targetId As Long = 0
3533
3534        If _curTab.Text = DEFAULTTAB.DM Then Exit Sub ' Directタブは対象外(見つかるはずがない)
3535        If _curList.SelectedIndices.Count = 0 Then Exit Sub '未選択も処理しない
3536
3537        targetId = GetCurTabPost(_curList.SelectedIndices(0)).Id
3538
3539        If left Then
3540            ' 左のタブへ
3541            If ListTab.SelectedIndex = 0 Then
3542                Exit Sub
3543            Else
3544                fIdx = ListTab.SelectedIndex - 1
3545            End If
3546            toIdx = 0
3547            stp = -1
3548        Else
3549            ' 右のタブへ
3550            If ListTab.SelectedIndex = ListTab.TabCount - 1 Then
3551                Exit Sub
3552            Else
3553                fIdx = ListTab.SelectedIndex + 1
3554            End If
3555            toIdx = ListTab.TabCount - 1
3556            stp = 1
3557        End If
3558
3559        Dim found As Boolean = False
3560        For tabidx As Integer = fIdx To toIdx Step stp
3561            If ListTab.TabPages(tabidx).Text = DEFAULTTAB.DM Then Continue For ' Directタブは対象外
3562            '_itemCache = Nothing
3563            '_postCache = Nothing
3564            For idx As Integer = 0 To DirectCast(ListTab.TabPages(tabidx).Controls(0), DetailsListView).VirtualListSize - 1
3565                If _statuses.Item(ListTab.TabPages(tabidx).Text, idx).Id = targetId Then
3566                    ListTab.SelectedIndex = tabidx
3567                    ListTabSelect(ListTab.TabPages(tabidx))
3568                    SelectListItem(_curList, idx)
3569                    _curList.EnsureVisible(idx)
3570                    found = True
3571                    Exit For
3572                End If
3573            Next
3574            If found Then Exit For
3575        Next
3576        '_itemCache = Nothing
3577        '_postCache = Nothing
3578    End Sub
3579
3580    Private Sub GoPost(ByVal forward As Boolean)
3581        If _curList.SelectedIndices.Count = 0 OrElse _curPost Is Nothing Then Exit Sub
3582        Dim fIdx As Integer = 0
3583        Dim toIdx As Integer = 0
3584        Dim stp As Integer = 1
3585
3586        If forward Then
3587            fIdx = _curList.SelectedIndices(0) + 1
3588            If fIdx > _curList.VirtualListSize - 1 Then Exit Sub
3589            toIdx = _curList.VirtualListSize - 1
3590            stp = 1
3591        Else
3592            fIdx = _curList.SelectedIndices(0) - 1
3593            If fIdx < 0 Then Exit Sub
3594            toIdx = 0
3595            stp = -1
3596        End If
3597
3598        For idx As Integer = fIdx To toIdx Step stp
3599            If _statuses.Item(_curTab.Text, idx).Name = _curPost.Name Then
3600                SelectListItem(_curList, idx)
3601                _curList.EnsureVisible(idx)
3602                Exit For
3603            End If
3604        Next
3605    End Sub
3606
3607    Private Sub GoRelPost(ByVal forward As Boolean)
3608        If _curList.SelectedIndices.Count = 0 Then Exit Sub
3609
3610        Dim fIdx As Integer = 0
3611        Dim toIdx As Integer = 0
3612        Dim stp As Integer = 1
3613        If forward Then
3614            fIdx = _curList.SelectedIndices(0) + 1
3615            If fIdx > _curList.VirtualListSize - 1 Then Exit Sub
3616            toIdx = _curList.VirtualListSize - 1
3617            stp = 1
3618        Else
3619            fIdx = _curList.SelectedIndices(0) - 1
3620            If fIdx < 0 Then Exit Sub
3621            toIdx = 0
3622            stp = -1
3623        End If
3624
3625        If Not _anchorFlag Then
3626            _anchorPost = _curPost
3627            _anchorFlag = True
3628        End If
3629
3630        For idx As Integer = fIdx To toIdx Step stp
3631            Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
3632            If post.Name = _anchorPost.Name OrElse _
3633               _anchorPost.ReplyToList.Contains(post.Name.ToLower()) OrElse _
3634               post.ReplyToList.Contains(_anchorPost.Name.ToLower()) Then
3635                SelectListItem(_curList, idx)
3636                _curList.EnsureVisible(idx)
3637                Exit For
3638            End If
3639        Next
3640    End Sub
3641
3642    Private Sub GoAnchor()
3643        If _anchorPost Is Nothing Then Exit Sub
3644        Dim idx As Integer = _statuses.Tabs(_curTab.Text).IndexOf(_anchorPost.Id)
3645        If idx = -1 Then Exit Sub
3646
3647        SelectListItem(_curList, idx)
3648        _curList.EnsureVisible(idx)
3649    End Sub
3650
3651    Private Sub GoTopEnd(ByVal GoTop As Boolean)
3652        Dim _item As ListViewItem
3653        Dim idx As Integer
3654
3655        If GoTop Then
3656            _item = _curList.GetItemAt(0, 25)
3657            If _item Is Nothing Then
3658                idx = 0
3659            Else
3660                idx = _item.Index
3661            End If
3662        Else
3663            _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1)
3664            If _item Is Nothing Then
3665                idx = _curList.VirtualListSize - 1
3666            Else
3667                idx = _item.Index
3668            End If
3669        End If
3670        SelectListItem(_curList, idx)
3671    End Sub
3672
3673    Private Sub GoMiddle()
3674        Dim _item As ListViewItem
3675        Dim idx1 As Integer
3676        Dim idx2 As Integer
3677        Dim idx3 As Integer
3678
3679        _item = _curList.GetItemAt(0, 0)
3680        If _item Is Nothing Then
3681            idx1 = 0
3682        Else
3683            idx1 = _item.Index
3684        End If
3685        _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1)
3686        If _item Is Nothing Then
3687            idx2 = _curList.VirtualListSize - 1
3688        Else
3689            idx2 = _item.Index
3690        End If
3691        idx3 = (idx1 + idx2) \ 2
3692
3693        SelectListItem(_curList, idx3)
3694    End Sub
3695
3696    Private Sub GoLast()
3697        If _curList.VirtualListSize = 0 Then Exit Sub
3698
3699        If _statuses.SortOrder = SortOrder.Ascending Then
3700            SelectListItem(_curList, _curList.VirtualListSize - 1)
3701            _curList.EnsureVisible(_curList.VirtualListSize - 1)
3702        Else
3703            SelectListItem(_curList, 0)
3704            _curList.EnsureVisible(0)
3705        End If
3706    End Sub
3707
3708    Private Sub MoveTop()
3709        If _curList.SelectedIndices.Count = 0 Then Exit Sub
3710        Dim idx As Integer = _curList.SelectedIndices(0)
3711        If _statuses.SortOrder = SortOrder.Ascending Then
3712            _curList.EnsureVisible(_curList.VirtualListSize - 1)
3713        Else
3714            _curList.EnsureVisible(0)
3715        End If
3716        _curList.EnsureVisible(idx)
3717    End Sub
3718
3719    Private Sub MyList_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
3720        _anchorFlag = False
3721    End Sub
3722
3723    Private Sub StatusText_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusText.Enter
3724        ' フォーカスの戻り先を StatusText に設定
3725        Me.Tag = StatusText
3726        StatusText.BackColor = _clInputBackcolor
3727    End Sub
3728
3729    Private Sub StatusText_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusText.Leave
3730        ' フォーカスがメニューに遷移しないならばフォーカスはタブに移ることを期待
3731        If ListTab.SelectedTab IsNot Nothing AndAlso MenuStrip1.Tag Is Nothing Then Me.Tag = ListTab.SelectedTab.Controls(0)
3732        StatusText.BackColor = Color.FromKnownColor(KnownColor.Window)
3733    End Sub
3734
3735    Private Sub StatusText_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles StatusText.KeyDown
3736        If e.Control AndAlso Not e.Alt AndAlso Not e.Shift Then
3737            If e.KeyCode = Keys.A Then
3738                StatusText.SelectAll()
3739            ElseIf e.KeyCode = Keys.Up OrElse e.KeyCode = Keys.Down Then
3740                If StatusText.Text.Trim() <> "" Then _history(_hisIdx) = StatusText.Text
3741                If e.KeyCode = Keys.Up Then
3742                    _hisIdx -= 1
3743                    If _hisIdx < 0 Then _hisIdx = 0
3744                Else
3745                    _hisIdx += 1
3746                    If _hisIdx > _history.Count - 1 Then _hisIdx = _history.Count - 1
3747                End If
3748                StatusText.Text = _history(_hisIdx)
3749                StatusText.SelectionStart = StatusText.Text.Length
3750                e.Handled = True
3751                e.SuppressKeyPress = True
3752            ElseIf e.KeyCode = Keys.PageUp Then
3753                If ListTab.SelectedIndex = 0 Then
3754                    ListTab.SelectedIndex = ListTab.TabCount - 1
3755                Else
3756                    ListTab.SelectedIndex -= 1
3757                End If
3758                e.Handled = True
3759                e.SuppressKeyPress = True
3760                StatusText.Focus()
3761            ElseIf e.KeyCode = Keys.PageDown Then
3762                If ListTab.SelectedIndex = ListTab.TabCount - 1 Then
3763                    ListTab.SelectedIndex = 0
3764                Else
3765                    ListTab.SelectedIndex += 1
3766                End If
3767                e.Handled = True
3768                e.SuppressKeyPress = True
3769                StatusText.Focus()
3770            End If
3771        End If
3772    End Sub
3773
3774    Private Sub SaveConfigsAll()
3775        SaveConfigsCommon()
3776        SaveConfigsLocal()
3777        SaveConfigsTab()
3778    End Sub
3779
3780    Private Sub SaveConfigsCommon()
3781        If _username <> "" AndAlso _password <> "" Then
3782            SyncLock _syncObject
3783                _cfgCommon.UserName = _username
3784                _cfgCommon.Password = _password
3785                _cfgCommon.NextPageThreshold = SettingDialog.NextPageThreshold
3786                _cfgCommon.NextPages = SettingDialog.NextPagesInt
3787                _cfgCommon.TimelinePeriod = SettingDialog.TimelinePeriodInt
3788                _cfgCommon.ReplyPeriod = SettingDialog.ReplyPeriodInt
3789                _cfgCommon.DMPeriod = SettingDialog.DMPeriodInt
3790                _cfgCommon.MaxPostNum = SettingDialog.MaxPostNum
3791                _cfgCommon.ReadPages = SettingDialog.ReadPages
3792                _cfgCommon.ReadPagesReply = SettingDialog.ReadPagesReply
3793                _cfgCommon.ReadPagesDM = SettingDialog.ReadPagesDM
3794                _cfgCommon.Read = SettingDialog.Readed
3795                _cfgCommon.IconSize = SettingDialog.IconSz
3796                _cfgCommon.UnreadManage = SettingDialog.UnreadManage
3797                _cfgCommon.PlaySound = SettingDialog.PlaySound
3798                _cfgCommon.OneWayLove = SettingDialog.OneWayLove
3799
3800                _cfgCommon.NameBalloon = SettingDialog.NameBalloon
3801                _cfgCommon.PostCtrlEnter = SettingDialog.PostCtrlEnter
3802                _cfgCommon.UseApi = SettingDialog.UseAPI
3803                _cfgCommon.CountApi = SettingDialog.CountApi
3804                _cfgCommon.UsePostMethod = False
3805                _cfgCommon.HubServer = SettingDialog.HubServer
3806                _cfgCommon.CheckReply = SettingDialog.CheckReply
3807                _cfgCommon.PostAndGet = SettingDialog.PostAndGet
3808                _cfgCommon.DispUsername = SettingDialog.DispUsername
3809                _cfgCommon.MinimizeToTray = SettingDialog.MinimizeToTray
3810                _cfgCommon.CloseToExit = SettingDialog.CloseToExit
3811                _cfgCommon.DispLatestPost = SettingDialog.DispLatestPost
3812                _cfgCommon.SortOrderLock = SettingDialog.SortOrderLock
3813                _cfgCommon.TinyUrlResolve = SettingDialog.TinyUrlResolve
3814                _cfgCommon.PeriodAdjust = SettingDialog.PeriodAdjust
3815                _cfgCommon.StartupVersion = SettingDialog.StartupVersion
3816                _cfgCommon.StartupKey = SettingDialog.StartupKey
3817                _cfgCommon.StartupFollowers = SettingDialog.StartupFollowers
3818                _cfgCommon.StartupApiModeNoWarning = SettingDialog.StartupAPImodeNoWarning
3819                _cfgCommon.RestrictFavCheck = SettingDialog.RestrictFavCheck
3820                _cfgCommon.AlwaysTop = SettingDialog.AlwaysTop
3821                _cfgCommon.UrlConvertAuto = SettingDialog.UrlConvertAuto
3822                _cfgCommon.Outputz = SettingDialog.OutputzEnabled
3823                _cfgCommon.OutputzKey = SettingDialog.OutputzKey
3824                _cfgCommon.OutputzUrlMode = SettingDialog.OutputzUrlmode
3825                _cfgCommon.UseUnreadStyle = SettingDialog.UseUnreadStyle
3826                _cfgCommon.DateTimeFormat = SettingDialog.DateTimeFormat
3827                _cfgCommon.DefaultTimeOut = SettingDialog.DefaultTimeOut
3828                _cfgCommon.ProtectNotInclude = SettingDialog.ProtectNotInclude
3829                _cfgCommon.LimitBalloon = SettingDialog.LimitBalloon
3830                _cfgCommon.AutoShortUrlFirst = SettingDialog.AutoShortUrlFirst
3831
3832                _cfgCommon.SortOrder = _statuses.SortOrder
3833                Select Case _statuses.SortMode
3834                    Case IdComparerClass.ComparerMode.Nickname  'ニックネーム
3835                        _cfgCommon.SortColumn = 1
3836                    Case IdComparerClass.ComparerMode.Data  '本文
3837                        _cfgCommon.SortColumn = 2
3838                    Case IdComparerClass.ComparerMode.Id  '時刻=発言Id
3839                        _cfgCommon.SortColumn = 3
3840                    Case IdComparerClass.ComparerMode.Name  '名前
3841                        _cfgCommon.SortColumn = 4
3842                    Case IdComparerClass.ComparerMode.Source  'Source
3843                        _cfgCommon.SortColumn = 7
3844                End Select
3845
3846                _cfgCommon.Save()
3847            End SyncLock
3848        End If
3849    End Sub
3850
3851    Private Sub SaveConfigsLocal()
3852        SyncLock _syncObject
3853            _cfgLocal.FormSize = _mySize
3854            _cfgLocal.FormLocation = _myLoc
3855            _cfgLocal.SplitterDistance = _mySpDis
3856            _cfgLocal.StatusMultiline = StatusText.Multiline
3857            _cfgLocal.StatusTextHeight = _mySpDis2
3858            _cfgLocal.StatusText = SettingDialog.Status
3859
3860            _cfgLocal.FontUnread = _fntUnread
3861            _cfgLocal.ColorUnread = _clUnread
3862            _cfgLocal.FontRead = _fntReaded
3863            _cfgLocal.ColorRead = _clReaded
3864            _cfgLocal.FontDetail = _fntDetail
3865            _cfgLocal.ColorFav = _clFav
3866            _cfgLocal.ColorOWL = _clOWL
3867            _cfgLocal.ColorSelf = _clSelf
3868            _cfgLocal.ColorAtSelf = _clAtSelf
3869            _cfgLocal.ColorTarget = _clTarget
3870            _cfgLocal.ColorAtTarget = _clAtTarget
3871            _cfgLocal.ColorAtFromTarget = _clAtFromTarget
3872            _cfgLocal.ColorAtTo = _clAtTo
3873            _cfgLocal.ColorInputBackcolor = _clInputBackcolor
3874            _cfgLocal.ColorInputFont = _clInputFont
3875            _cfgLocal.FontInputFont = _fntInputFont
3876
3877            _cfgLocal.BrowserPath = SettingDialog.BrowserPath
3878            _cfgLocal.UseRecommendStatus = SettingDialog.UseRecommendStatus
3879            _cfgLocal.ProxyType = SettingDialog.ProxyType
3880            _cfgLocal.ProxyAddress = SettingDialog.ProxyAddress
3881            _cfgLocal.ProxyPort = SettingDialog.ProxyPort
3882            _cfgLocal.ProxyUser = SettingDialog.ProxyUser
3883            _cfgLocal.ProxyPassword = SettingDialog.ProxyPassword
3884
3885            _cfgLocal.Save()
3886        End SyncLock
3887    End Sub
3888
3889    Private Sub SaveConfigsTab()
3890        SyncLock _syncObject
3891            Dim cnt As Integer = 0
3892            If ListTab IsNot Nothing AndAlso _
3893               ListTab.TabPages IsNot Nothing AndAlso _
3894               ListTab.TabPages.Count > 0 Then
3895                _cfgCommon.TabList.Clear()
3896                SettingTab.DeleteConfigFile()   '旧設定ファイル削除
3897                For cnt = 0 To ListTab.TabPages.Count - 1
3898                    _cfgCommon.TabList.Add(ListTab.TabPages(cnt).Text)
3899                    Dim tabSetting As New SettingTab
3900                    tabSetting.Tab = _statuses.Tabs(ListTab.TabPages(cnt).Text)
3901                    tabSetting.Save()
3902                Next
3903            End If
3904        End SyncLock
3905    End Sub
3906
3907    Private Sub SaveLogMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveLogMenuItem.Click
3908        Dim rslt As DialogResult = MessageBox.Show(String.Format(My.Resources.SaveLogMenuItem_ClickText1, Environment.NewLine), _
3909                My.Resources.SaveLogMenuItem_ClickText2, _
3910                MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)
3911        If rslt = Windows.Forms.DialogResult.Cancel Then Exit Sub
3912
3913        SaveFileDialog1.FileName = "TweenPosts" + Format(Now, "yyMMdd-HHmmss") + ".tsv"
3914        SaveFileDialog1.InitialDirectory = My.Application.Info.DirectoryPath
3915        SaveFileDialog1.Filter = My.Resources.SaveLogMenuItem_ClickText3
3916        SaveFileDialog1.FilterIndex = 0
3917        SaveFileDialog1.Title = My.Resources.SaveLogMenuItem_ClickText4
3918        SaveFileDialog1.RestoreDirectory = True
3919
3920        If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
3921            If Not SaveFileDialog1.ValidateNames Then Exit Sub
3922            Using sw As StreamWriter = New StreamWriter(SaveFileDialog1.FileName, False, Encoding.UTF8)
3923                If rslt = Windows.Forms.DialogResult.Yes Then
3924                    'All
3925                    For idx As Integer = 0 To _curList.VirtualListSize - 1
3926                        Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
3927                        sw.WriteLine(post.Nickname & vbTab & _
3928                                 """" & post.Data.Replace(vbLf, "").Replace("""", """""") + """" & vbTab & _
3929                                 post.PDate.ToString() & vbTab & _
3930                                 post.Name & vbTab & _
3931                                 post.Id.ToString() & vbTab & _
3932                                 post.ImageUrl & vbTab & _
3933                                 """" & post.OriginalData.Replace(vbLf, "").Replace("""", """""") + """")
3934                    Next
3935                Else
3936                    For Each idx As Integer In _curList.SelectedIndices
3937                        Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
3938                        sw.WriteLine(post.Nickname & vbTab & _
3939                                 """" & post.Data.Replace(vbLf, "").Replace("""", """""") + """" & vbTab & _
3940                                 post.PDate.ToString() & vbTab & _
3941                                 post.Name & vbTab & _
3942                                 post.Id.ToString() & vbTab & _
3943                                 post.ImageUrl & vbTab & _
3944                                 """" & post.OriginalData.Replace(vbLf, "").Replace("""", """""") + """")
3945                    Next
3946                End If
3947            End Using
3948        End If
3949        Me.TopMost = SettingDialog.AlwaysTop
3950    End Sub
3951
3952    Private Sub PostBrowser_PreviewKeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles PostBrowser.PreviewKeyDown
3953        If e.KeyCode = Keys.F5 OrElse e.KeyCode = Keys.R Then
3954            e.IsInputKey = True
3955            DoRefresh()
3956        End If
3957        If e.Modifiers = Keys.None AndAlso (e.KeyCode = Keys.Space OrElse e.KeyCode = Keys.ProcessKey) Then
3958            e.IsInputKey = True
3959            JumpUnreadMenuItem_Click(Nothing, Nothing)
3960        End If
3961    End Sub
3962
3963    Private Sub TabRename()
3964        'タブ名変更
3965        If IsDefaultTab(ListTab.SelectedTab.Text) Then Exit Sub
3966        Dim newTabText As String = Nothing
3967        Using inputName As New InputTabName()
3968            inputName.TabName = ListTab.SelectedTab.Text
3969            inputName.ShowDialog()
3970            newTabText = inputName.TabName
3971        End Using
3972        Me.TopMost = SettingDialog.AlwaysTop
3973        If newTabText <> "" Then
3974            '新タブ名存在チェック
3975            For i As Integer = 0 To ListTab.TabCount - 1
3976                If ListTab.TabPages(i).Text = newTabText Then
3977                    Dim tmp As String = String.Format(My.Resources.Tabs_DoubleClickText1, newTabText)
3978                    MessageBox.Show(tmp, My.Resources.Tabs_DoubleClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
3979                    Exit Sub
3980                End If
3981            Next
3982            'タブ名のリスト作り直し(デフォルトタブ以外は再作成)
3983            For i As Integer = 0 To ListTab.TabCount - 1
3984                If Not IsDefaultTab(ListTab.TabPages(i).Text) Then
3985                    TabDialog.RemoveTab(ListTab.TabPages(i).Text)
3986                End If
3987            Next
3988            _statuses.RenameTab(ListTab.SelectedTab.Text, newTabText)
3989            ListTab.SelectedTab.Text = newTabText   'タブ名変更反映
3990            For i As Integer = 0 To ListTab.TabCount - 1
3991                If Not IsDefaultTab(ListTab.TabPages(i).Text) Then
3992                    TabDialog.AddTab(ListTab.TabPages(i).Text)
3993                End If
3994            Next
3995            SaveConfigsCommon()
3996            SaveConfigsTab()
3997            _rclickTabName = newTabText
3998        End If
3999    End Sub
4000
4001    Private Sub Tabs_DoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseDoubleClick
4002        TabRename()
4003    End Sub
4004
4005    Private Sub Tabs_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseDown
4006        Dim cpos As New Point(e.X, e.Y)
4007        If e.Button = Windows.Forms.MouseButtons.Left Then
4008            For i As Integer = 0 To ListTab.TabPages.Count - 1
4009                Dim rect As Rectangle = ListTab.GetTabRect(i)
4010                If rect.Left <= cpos.X AndAlso cpos.X <= rect.Right AndAlso _
4011                   rect.Top <= cpos.Y AndAlso cpos.Y <= rect.Bottom Then
4012                    _tabDrag = True
4013                    Exit For
4014                End If
4015            Next
4016        Else
4017            _tabDrag = False
4018        End If
4019    End Sub
4020
4021    Private Sub Tabs_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListTab.DragEnter
4022        If e.Data.GetDataPresent(GetType(TabPage)) Then
4023            e.Effect = DragDropEffects.Move
4024        Else
4025            e.Effect = DragDropEffects.None
4026        End If
4027    End Sub
4028
4029    Private Sub Tabs_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListTab.DragDrop
4030        If Not e.Data.GetDataPresent(GetType(TabPage)) Then Exit Sub
4031
4032        _tabDrag = False
4033        Dim tn As String = ""
4034        Dim bef As Boolean
4035        Dim cpos As New Point(e.X, e.Y)
4036        Dim spos As Point = ListTab.PointToClient(cpos)
4037        Dim i As Integer
4038        For i = 0 To ListTab.TabPages.Count - 1
4039            Dim rect As Rectangle = ListTab.GetTabRect(i)
4040            If rect.Left <= spos.X AndAlso spos.X <= rect.Right AndAlso _
4041               rect.Top <= spos.Y AndAlso spos.Y <= rect.Bottom Then
4042                tn = ListTab.TabPages(i).Text
4043                If spos.X <= (rect.Left + rect.Right) / 2 Then
4044                    bef = True
4045                Else
4046                    bef = False
4047                End If
4048                Exit For
4049            End If
4050        Next
4051
4052        'タブのないところにドロップ->最後尾へ移動
4053        If tn = "" Then
4054            tn = ListTab.TabPages(ListTab.TabPages.Count - 1).Text
4055            bef = False
4056            i = ListTab.TabPages.Count - 1
4057        End If
4058
4059        Dim tp As TabPage = DirectCast(e.Data.GetData(GetType(TabPage)), TabPage)
4060        If tp.Text = tn Then Exit Sub
4061
4062        Dim mTp As TabPage = Nothing
4063        ListTab.SuspendLayout()
4064        For j As Integer = 0 To ListTab.TabPages.Count - 1
4065            If ListTab.TabPages(j).Text = tp.Text Then
4066                mTp = ListTab.TabPages(j)
4067                ListTab.TabPages.Remove(mTp)
4068                If j < i Then i -= 1
4069                Exit For
4070            End If
4071        Next
4072        If bef Then
4073            ListTab.TabPages.Insert(i, mTp)
4074        Else
4075            ListTab.TabPages.Insert(i + 1, mTp)
4076        End If
4077        ListTab.ResumeLayout()
4078        SaveConfigsCommon()
4079    End Sub
4080
4081    Private Sub MakeReplyOrDirectStatus(Optional ByVal isAuto As Boolean = True, Optional ByVal isReply As Boolean = True, Optional ByVal isAll As Boolean = False)
4082        'isAuto:True=先頭に挿入、False=カーソル位置に挿入
4083        'isReply:True=@,False=DM
4084        If Not StatusText.Enabled Then Exit Sub
4085
4086        ' 複数あてリプライはReplyではなく通常ポスト
4087        '↑仕様変更で全部リプライ扱いでOK(先頭ドット付加しない)
4088        '090403暫定でドットを付加しないようにだけ修正。単独と複数の処理は統合できると思われる。
4089        '090513 all @ replies 廃止の仕様変更によりドット付加に戻し(syo68k)
4090
4091        If _curList.SelectedIndices.Count > 0 Then
4092            ' アイテムが1件以上選択されている
4093            If _curList.SelectedIndices.Count = 1 AndAlso Not isAll AndAlso _curPost IsNot Nothing Then
4094                ' 単独ユーザー宛リプライまたはDM
4095                If (ListTab.SelectedTab.Text = DEFAULTTAB.DM AndAlso isAuto) OrElse (Not isAuto AndAlso Not isReply) Then
4096                    ' ダイレクトメッセージ
4097                    StatusText.Text = "D " + _curPost.Name + " " + StatusText.Text
4098                    StatusText.SelectionStart = StatusText.Text.Length
4099                    StatusText.Focus()
4100                    _reply_to_id = 0
4101                    _reply_to_name = Nothing
4102                    Exit Sub
4103                End If
4104                If StatusText.Text = "" Then
4105                    ' ステータステキストが入力されていない場合先頭に@ユーザー名を追加する
4106                    StatusText.Text = "@" + _curPost.Name + " "
4107                    _reply_to_id = _curPost.Id
4108                    _reply_to_name = _curPost.Name
4109                Else
4110                    If isAuto Then
4111                        If StatusText.Text.Contains("@" + _curPost.Name + " ") Then Exit Sub
4112                        If Not StatusText.Text.StartsWith("@") Then
4113                            If StatusText.Text.StartsWith(". ") Then
4114                                ' 複数リプライ
4115                                StatusText.Text = StatusText.Text.Insert(2, "@" + _curPost.Name + " ")
4116                                _reply_to_id = 0
4117                                _reply_to_name = Nothing
4118                            Else
4119                                ' 単独リプライ
4120                                StatusText.Text = "@" + _curPost.Name + " " + StatusText.Text
4121                                _reply_to_id = _curPost.Id
4122                                _reply_to_name = _curPost.Name
4123                            End If
4124                        Else
4125                            ' 複数リプライ
4126                            StatusText.Text = ". @" + _curPost.Name + " " + StatusText.Text
4127                            'StatusText.Text = "@" + _curPost.Name + " " + StatusText.Text
4128                            _reply_to_id = 0
4129                            _reply_to_name = Nothing
4130                        End If
4131                    Else
4132                        Dim sidx As Integer = StatusText.SelectionStart
4133                        If StatusText.Text.StartsWith("@") Then
4134                            '複数リプライ
4135                            StatusText.Text = ". " + StatusText.Text.Insert(sidx, " @" + _curPost.Name + " ")
4136                            sidx += 5 + _curPost.Name.Length
4137                        Else
4138                            ' 複数リプライ
4139                            StatusText.Text = StatusText.Text.Insert(sidx, " @" + _curPost.Name + " ")
4140                            sidx += 3 + _curPost.Name.Length
4141                        End If
4142                        StatusText.SelectionStart = sidx
4143                        StatusText.Focus()
4144                        _reply_to_id = 0
4145                        _reply_to_name = Nothing
4146                        Exit Sub
4147                    End If
4148                End If
4149            Else
4150                ' 複数リプライ
4151                If Not isAuto AndAlso Not isReply Then Exit Sub
4152
4153                If isAuto Then
4154                    Dim sTxt As String = StatusText.Text
4155                    If Not sTxt.StartsWith(". ") Then
4156                        sTxt = ". " + sTxt
4157                    End If
4158                    For cnt As Integer = 0 To _curList.SelectedIndices.Count - 1
4159                        Dim post As PostClass = _statuses.Item(_curTab.Text, _curList.SelectedIndices(cnt))
4160                        If Not sTxt.Contains("@" + post.Name + " ") Then
4161                            sTxt = sTxt.Insert(2, "@" + post.Name + " ")
4162                            'sTxt = "@" + post.Name + " " + sTxt
4163                        End If
4164                    Next
4165                    StatusText.Text = sTxt
4166                Else
4167                    Dim ids As String = ""
4168                    Dim sidx As Integer = StatusText.SelectionStart
4169                    For cnt As Integer = 0 To _curList.SelectedIndices.Count - 1
4170                        Dim post As PostClass = _statuses.Item(_curTab.Text, _curList.SelectedIndices(cnt))
4171                        If Not ids.Contains("@" + post.Name + " ") AndAlso _
4172                           Not post.Name.Equals(_username, StringComparison.CurrentCultureIgnoreCase) Then
4173                            ids += "@" + post.Name + " "
4174                        End If
4175                        If isAll Then
4176                            For Each nm As String In post.ReplyToList
4177                                If Not ids.Contains("@" + nm + " ") AndAlso _
4178                                   Not nm.Equals(_username, StringComparison.CurrentCultureIgnoreCase) Then
4179                                    ids += "@" + nm + " "
4180                                End If
4181                            Next
4182                        End If
4183                    Next
4184                    If ids.Length = 0 Then Exit Sub
4185                    If Not StatusText.Text.StartsWith(". ") Then
4186                        StatusText.Text = ". " + StatusText.Text
4187                        sidx += 2
4188                    End If
4189                    If sidx > 0 Then
4190                        If StatusText.Text.Substring(sidx - 1, 1) <> " " Then
4191                            ids = " " + ids
4192                        End If
4193                    End If
4194                    If StatusText.Text.StartsWith("@") Then
4195                        StatusText.Text = ". " + StatusText.Text.Insert(sidx, ids)
4196                        sidx += 2 + ids.Length
4197                    Else
4198                        StatusText.Text = StatusText.Text.Insert(sidx, ids)
4199                        sidx += 1 + ids.Length
4200                    End If
4201                    StatusText.SelectionStart = sidx
4202                    StatusText.Focus()
4203                    Exit Sub
4204                End If
4205            End If
4206            StatusText.SelectionStart = StatusText.Text.Length
4207            StatusText.Focus()
4208        End If
4209    End Sub
4210
4211    Private Sub ListTab_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListTab.MouseUp
4212        _tabDrag = False
4213    End Sub
4214
4215    Private Sub TimerRefreshIcon_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerRefreshIcon.Tick
4216        If Not TimerRefreshIcon.Enabled Then Exit Sub
4217        Static iconCnt As Integer = 0
4218
4219        iconCnt += 1
4220        If iconCnt > 3 Then iconCnt = 0
4221
4222        NotifyIcon1.Icon = NIconRefresh(iconCnt)
4223    End Sub
4224
4225    Private Sub ContextMenuTabProperty_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuTabProperty.Opening
4226        '右クリックの場合はタブ名が設定済。アプリケーションキーの場合は現在のタブを対象とする
4227        If _rclickTabName = "" OrElse ContextMenuTabProperty.OwnerItem IsNot Nothing Then _rclickTabName = ListTab.SelectedTab.Text
4228
4229        Dim tb As TabClass = _statuses.Tabs(_rclickTabName)
4230
4231        NotifyDispMenuItem.Checked = tb.Notify
4232        SoundFileComboBox.Items.Clear()
4233        SoundFileComboBox.Items.Add("")
4234        Dim oDir As IO.DirectoryInfo = New IO.DirectoryInfo(My.Application.Info.DirectoryPath)
4235        For Each oFile As IO.FileInfo In oDir.GetFiles("*.wav")
4236            SoundFileComboBox.Items.Add(oFile.Name)
4237        Next
4238        Dim idx As Integer = SoundFileComboBox.Items.IndexOf(tb.SoundFile)
4239        If idx = -1 Then idx = 0
4240        SoundFileComboBox.SelectedIndex = idx
4241        UreadManageMenuItem.Checked = tb.UnreadManage
4242        If _rclickTabName = DEFAULTTAB.RECENT OrElse _rclickTabName = DEFAULTTAB.DM OrElse _rclickTabName = DEFAULTTAB.FAV Then
4243            FilterEditMenuItem.Enabled = False
4244            DeleteTabMenuItem.Enabled = False
4245        ElseIf _rclickTabName = DEFAULTTAB.REPLY Then
4246            FilterEditMenuItem.Enabled = True
4247            DeleteTabMenuItem.Enabled = False
4248        Else
4249            FilterEditMenuItem.Enabled = True
4250            DeleteTabMenuItem.Enabled = True
4251        End If
4252    End Sub
4253
4254    Private Sub UreadManageMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UreadManageMenuItem.Click
4255        If _rclickTabName = "" Then Exit Sub
4256        Dim idx As Integer
4257
4258        For idx = 0 To ListTab.TabCount
4259            If ListTab.TabPages(idx).Text = _rclickTabName Then Exit For
4260        Next
4261
4262        _statuses.SetTabUnreadManage(_rclickTabName, UreadManageMenuItem.Checked)
4263        If _statuses.Tabs(_rclickTabName).UnreadCount > 0 Then
4264            ListTab.TabPages(idx).ImageIndex = 0
4265        Else
4266            ListTab.TabPages(idx).ImageIndex = -1
4267        End If
4268        If _curTab.Text = _rclickTabName Then
4269            _itemCache = Nothing
4270            _postCache = Nothing
4271            _curList.Refresh()
4272        End If
4273        SetMainWindowTitle()
4274        SetStatusLabel()
4275    End Sub
4276
4277    Private Sub NotifyDispMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NotifyDispMenuItem.Click
4278        If _rclickTabName = "" Then Exit Sub
4279
4280        Dim tb As TabClass = _statuses.Tabs(_rclickTabName)
4281        tb.Notify = NotifyDispMenuItem.Checked
4282    End Sub
4283
4284    Private Sub SoundFileComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SoundFileComboBox.SelectedIndexChanged
4285        If _rclickTabName = "" Then Exit Sub
4286
4287        Dim tb As TabClass = _statuses.Tabs(_rclickTabName)
4288        tb.SoundFile = DirectCast(SoundFileComboBox.SelectedItem, String)
4289    End Sub
4290
4291    Private Sub DeleteTabMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DeleteTabMenuItem.Click
4292        If _rclickTabName = "" Then Exit Sub
4293
4294        RemoveSpecifiedTab(_rclickTabName)
4295        _rclickTabName = ""
4296    End Sub
4297
4298    Private Sub FilterEditMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FilterEditMenuItem.Click
4299        If _rclickTabName = "" OrElse _rclickTabName = DEFAULTTAB.RECENT OrElse _rclickTabName = DEFAULTTAB.DM _
4300                OrElse _rclickTabName = DEFAULTTAB.FAV Then Exit Sub
4301
4302        fDialog.SetCurrent(_rclickTabName)
4303        fDialog.ShowDialog()
4304        SaveConfigsTab()
4305        Me.TopMost = SettingDialog.AlwaysTop
4306
4307        Try
4308            Me.Cursor = Cursors.WaitCursor
4309            _itemCache = Nothing
4310            _postCache = Nothing
4311            _curPost = Nothing
4312            _curItemIndex = -1
4313            _statuses.FilterAll()
4314            For Each tb As TabPage In ListTab.TabPages
4315                DirectCast(tb.Controls(0), DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
4316                If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
4317                    tb.ImageIndex = 0
4318                Else
4319                    tb.ImageIndex = -1
4320                End If
4321            Next
4322        Finally
4323            Me.Cursor = Cursors.Default
4324        End Try
4325    End Sub
4326
4327    Private Sub AddTabMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddTabMenuItem.Click
4328        Dim tabName As String = Nothing
4329        Using inputName As New InputTabName()
4330            inputName.TabName = "MyTab" + (ListTab.TabPages.Count + 1).ToString
4331            inputName.ShowDialog()
4332            tabName = inputName.TabName
4333        End Using
4334        Me.TopMost = SettingDialog.AlwaysTop
4335        If tabName <> "" Then
4336            If Not AddNewTab(tabName, False) Then
4337                Dim tmp As String = String.Format(My.Resources.AddTabMenuItem_ClickText1, tabName)
4338                MessageBox.Show(tmp, My.Resources.AddTabMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
4339            Else
4340                '成功
4341                _statuses.AddTab(tabName)
4342                SaveConfigsCommon()
4343                SaveConfigsTab()
4344            End If
4345        End If
4346    End Sub
4347
4348    Private Sub TabMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TabMenuItem.Click
4349        '選択発言を元にフィルタ追加
4350        For Each idx As Integer In _curList.SelectedIndices
4351            Dim tabName As String = ""
4352            Do
4353                '振り分け先タブ選択
4354                If TabDialog.ShowDialog = Windows.Forms.DialogResult.Cancel Then
4355                    Me.TopMost = SettingDialog.AlwaysTop
4356                    Exit Sub
4357                End If
4358                Me.TopMost = SettingDialog.AlwaysTop
4359                tabName = TabDialog.SelectedTabName
4360
4361                ListTab.SelectedTab.Focus()
4362                '新規タブが選択→タブ追加
4363                If tabName = My.Resources.TabMenuItem_ClickText1 Then
4364                    Using inputName As New InputTabName()
4365                        inputName.TabName = "MyTab" + ListTab.TabPages.Count.ToString
4366                        inputName.ShowDialog()
4367                        tabName = inputName.TabName
4368                    End Using
4369                    Me.TopMost = SettingDialog.AlwaysTop
4370                    If tabName.Length > 0 Then
4371                        If Not AddNewTab(tabName, False) Then
4372                            Dim tmp As String = String.Format(My.Resources.TabMenuItem_ClickText2, tabName)
4373                            MessageBox.Show(tmp, My.Resources.TabMenuItem_ClickText3, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
4374                        Else
4375                            _statuses.AddTab(tabName)
4376                            Exit Do
4377                        End If
4378                    End If
4379                Else
4380                    Exit Do
4381                End If
4382            Loop While True
4383            fDialog.SetCurrent(tabName)
4384            fDialog.AddNewFilter(_statuses.Item(_curTab.Text, idx).Name, _statuses.Item(_curTab.Text, idx).Data)
4385            fDialog.ShowDialog()
4386            Me.TopMost = SettingDialog.AlwaysTop
4387        Next
4388
4389        Try
4390            Me.Cursor = Cursors.WaitCursor
4391            _itemCache = Nothing
4392            _postCache = Nothing
4393            _curPost = Nothing
4394            _curItemIndex = -1
4395            _statuses.FilterAll()
4396            For Each tb As TabPage In ListTab.TabPages
4397                DirectCast(tb.Controls(0), DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
4398                If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
4399                    tb.ImageIndex = 0
4400                Else
4401                    tb.ImageIndex = -1
4402                End If
4403            Next
4404        Finally
4405            Me.Cursor = Cursors.Default
4406        End Try
4407        SaveConfigsCommon()
4408        SaveConfigsTab()
4409    End Sub
4410
4411    Protected Overrides Function ProcessDialogKey( _
4412        ByVal keyData As Keys) As Boolean
4413        'TextBox1でEnterを押してもビープ音が鳴らないようにする
4414        If StatusText.Focused AndAlso _
4415            (keyData And Keys.KeyCode) = Keys.Enter Then
4416            '改行
4417            If StatusText.Multiline AndAlso _
4418               ((keyData And Keys.Shift) = Keys.Shift OrElse _
4419               ((keyData And Keys.Control) = Keys.Control AndAlso Not SettingDialog.PostCtrlEnter) OrElse _
4420               ((keyData And Keys.Shift) <> Keys.Shift AndAlso (keyData And Keys.Control) <> Keys.Control AndAlso SettingDialog.PostCtrlEnter)) Then
4421                Dim pos1 As Integer = StatusText.SelectionStart
4422                If StatusText.SelectionLength > 0 Then
4423                    StatusText.Text = StatusText.Text.Remove(pos1, StatusText.SelectionLength)  '選択状態文字列削除
4424                End If
4425                StatusText.Text = StatusText.Text.Insert(pos1, Environment.NewLine)  '改行挿入
4426                StatusText.SelectionStart = pos1 + Environment.NewLine.Length    'カーソルを改行の次の文字へ移動
4427                Return True
4428            End If
4429            '投稿
4430            If ((keyData And Keys.Control) = Keys.Control AndAlso SettingDialog.PostCtrlEnter) OrElse _
4431               ((keyData And Keys.Control) <> Keys.Control AndAlso Not SettingDialog.PostCtrlEnter) Then
4432                PostButton_Click(Nothing, Nothing)
4433                Return True
4434            End If
4435        End If
4436        Return MyBase.ProcessDialogKey(keyData)
4437    End Function
4438
4439    Private Sub InfoTwitterMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles InfoTwitterMenuItem.Click
4440        If Twitter.InfoTwitter.Trim() = "" Then
4441            MessageBox.Show(My.Resources.InfoTwitterMenuItem_ClickText1, My.Resources.InfoTwitterMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Information)
4442        Else
4443            Dim inf As String = Twitter.InfoTwitter.Trim()
4444            inf = "<html><head></head><body>" + inf + "</body></html>"
4445            PostBrowser.Visible = False
4446            PostBrowser.DocumentText = inf
4447            PostBrowser.Visible = True
4448        End If
4449    End Sub
4450
4451    Private Sub ReplyAllStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReplyAllStripMenuItem.Click
4452        MakeReplyOrDirectStatus(False, True, True)
4453    End Sub
4454
4455    Private Sub IDRuleMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IDRuleMenuItem.Click
4456        Dim tabName As String = ""
4457
4458        '未選択なら処理終了
4459        If _curList.SelectedIndices.Count = 0 Then Exit Sub
4460
4461        Do
4462            '振り分け先タブ選択
4463            If TabDialog.ShowDialog = Windows.Forms.DialogResult.Cancel Then
4464                Me.TopMost = SettingDialog.AlwaysTop
4465                Exit Sub
4466            End If
4467            Me.TopMost = SettingDialog.AlwaysTop
4468            tabName = TabDialog.SelectedTabName
4469
4470            ListTab.SelectedTab.Focus()
4471            '新規タブを選択→タブ作成
4472            If tabName = My.Resources.IDRuleMenuItem_ClickText1 Then
4473                Using inputName As New InputTabName()
4474                    inputName.TabName = "MyTab" + ListTab.TabPages.Count.ToString
4475                    inputName.ShowDialog()
4476                    tabName = inputName.TabName
4477                End Using
4478                Me.TopMost = SettingDialog.AlwaysTop
4479                If tabName <> "" Then
4480                    If Not AddNewTab(tabName, False) Then
4481                        Dim tmp As String = String.Format(My.Resources.IDRuleMenuItem_ClickText2, tabName)
4482                        MessageBox.Show(tmp, My.Resources.IDRuleMenuItem_ClickText3, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
4483                    Else
4484                        _statuses.AddTab(tabName)
4485                        Exit Do
4486                    End If
4487                End If
4488            Else
4489                '既存タブを選択
4490                Exit Do
4491            End If
4492        Loop While True
4493        Dim mv As Boolean = False
4494        With Block
4495            '移動するか?
4496            Dim _tmp As String = String.Format(My.Resources.IDRuleMenuItem_ClickText4, Environment.NewLine)
4497            If MessageBox.Show(_tmp, My.Resources.IDRuleMenuItem_ClickText5, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
4498                mv = False
4499            Else
4500                mv = True
4501            End If
4502        End With
4503        Dim mk As Boolean = False
4504        If Not mv Then
4505            'マークするか?
4506            Dim _tmp As String = String.Format(My.Resources.IDRuleMenuItem_ClickText6, vbCrLf)
4507            If MessageBox.Show(_tmp, My.Resources.IDRuleMenuItem_ClickText7, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
4508                mk = True
4509            Else
4510                mk = False
4511            End If
4512        End If
4513        Dim ids As New List(Of String)
4514        For Each idx As Integer In _curList.SelectedIndices
4515            Dim post As PostClass = _statuses.Item(_curTab.Text, idx)
4516            If Not ids.Contains(post.Name) Then
4517                Dim fc As New FiltersClass
4518                ids.Add(post.Name)
4519                fc.NameFilter = post.Name
4520                fc.SearchBoth = True
4521                fc.MoveFrom = mv
4522                fc.SetMark = mk
4523                fc.UseRegex = False
4524                fc.SearchUrl = False
4525                _statuses.Tabs(tabName).AddFilter(fc)
4526            End If
4527        Next
4528
4529        Try
4530            Me.Cursor = Cursors.WaitCursor
4531            _itemCache = Nothing
4532            _postCache = Nothing
4533            _curPost = Nothing
4534            _curItemIndex = -1
4535            _statuses.FilterAll()
4536            For Each tb As TabPage In ListTab.TabPages
4537                DirectCast(tb.Controls(0), DetailsListView).VirtualListSize = _statuses.Tabs(tb.Text).AllCount
4538                If _statuses.Tabs(tb.Text).UnreadCount > 0 Then
4539                    tb.ImageIndex = 0
4540                Else
4541                    tb.ImageIndex = -1
4542                End If
4543            Next
4544        Finally
4545            Me.Cursor = Cursors.Default
4546        End Try
4547        SaveConfigsCommon()
4548        SaveConfigsTab()
4549    End Sub
4550
4551    Private Sub CopySTOTMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CopySTOTMenuItem.Click
4552        Me.CopyStot()
4553    End Sub
4554
4555    Private Sub CopyURLMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CopyURLMenuItem.Click
4556        Me.CopyIdUri()
4557    End Sub
4558
4559    Private Sub SelectAllMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectAllMenuItem.Click
4560        If StatusText.Focused Then
4561            ' 発言欄でのCtrl+A
4562            StatusText.SelectAll()
4563        Else
4564            ' ListView上でのCtrl+A
4565            For i As Integer = 0 To _curList.VirtualListSize - 1
4566                _curList.SelectedIndices.Add(i)
4567            Next
4568        End If
4569    End Sub
4570
4571    Private Sub MoveMiddle()
4572        Dim _item As ListViewItem
4573        Dim idx1 As Integer
4574        Dim idx2 As Integer
4575
4576        If _curList.SelectedIndices.Count = 0 Then Exit Sub
4577
4578        Dim idx As Integer = _curList.SelectedIndices(0)
4579
4580        _item = _curList.GetItemAt(0, 25)
4581        If _item Is Nothing Then
4582            idx1 = 0
4583        Else
4584            idx1 = _item.Index
4585        End If
4586        _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1)
4587        If _item Is Nothing Then
4588            idx2 = _curList.VirtualListSize - 1
4589        Else
4590            idx2 = _item.Index
4591        End If
4592
4593        idx -= Math.Abs(idx1 - idx2) \ 2
4594        If idx < 0 Then idx = 0
4595
4596        _curList.EnsureVisible(_curList.VirtualListSize - 1)
4597        _curList.EnsureVisible(idx)
4598    End Sub
4599
4600    Private Sub WedataMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles WedataMenuItem.Click
4601        Twitter.GetWedata()
4602    End Sub
4603
4604    Private Sub OpenURLMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenURLMenuItem.Click
4605        If PostBrowser.Document.Links.Count > 0 Then
4606            UrlDialog.ClearUrl()
4607
4608            Dim openUrlStr As String = ""
4609
4610            If PostBrowser.Document.Links.Count = 1 Then
4611                Dim urlStr As String = IDNDecode(PostBrowser.Document.Links(0).GetAttribute("href"))
4612                If urlStr Is Nothing Then Exit Sub
4613                openUrlStr = urlEncodeMultibyteChar(urlStr)
4614            Else
4615                For Each linkElm As System.Windows.Forms.HtmlElement In PostBrowser.Document.Links
4616                    Dim urlStr As String = IDNDecode(linkElm.GetAttribute("href"))
4617                    If urlStr Is Nothing Then Continue For
4618                    UrlDialog.AddUrl(urlEncodeMultibyteChar(urlStr))
4619                Next
4620                If UrlDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
4621                    openUrlStr = UrlDialog.SelectedUrl
4622                End If
4623                Me.TopMost = SettingDialog.AlwaysTop
4624            End If
4625
4626            If openUrlStr <> "" Then OpenUriAsync(openUrlStr)
4627        End If
4628    End Sub
4629
4630    Private Sub ClearTabMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ClearTabMenuItem.Click
4631        If _rclickTabName = "" Then Exit Sub
4632        Dim tmp As String = String.Format(My.Resources.ClearTabMenuItem_ClickText1, Environment.NewLine)
4633        If MessageBox.Show(tmp, My.Resources.ClearTabMenuItem_ClickText2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
4634            Exit Sub
4635        End If
4636
4637        _statuses.ClearTabIds(_rclickTabName)
4638        If ListTab.SelectedTab.Text = _rclickTabName Then
4639            _anchorPost = Nothing
4640            _anchorFlag = False
4641            _itemCache = Nothing
4642            _postCache = Nothing
4643            _itemCacheIndex = -1
4644            _curItemIndex = -1
4645            _curPost = Nothing
4646        End If
4647        For Each tb As TabPage In ListTab.TabPages
4648            If tb.Text = _rclickTabName Then
4649                tb.ImageIndex = -1
4650                DirectCast(tb.Controls(0), DetailsListView).VirtualListSize = 0
4651                Exit For
4652            End If
4653        Next
4654
4655        SetMainWindowTitle()
4656        SetStatusLabel()
4657    End Sub
4658
4659    Private Sub SetMainWindowTitle()
4660        'メインウインドウタイトルの書き換え
4661        Dim ttl As New StringBuilder(256)
4662        Dim ur As Integer = 0
4663        Dim al As Integer = 0
4664        Static myVer As String = My.Application.Info.Version.ToString()
4665        If SettingDialog.DispLatestPost <> DispTitleEnum.None AndAlso _
4666           SettingDialog.DispLatestPost <> DispTitleEnum.Post AndAlso _
4667           SettingDialog.DispLatestPost <> DispTitleEnum.Ver Then
4668            For Each key As String In _statuses.Tabs.Keys
4669                ur += _statuses.Tabs(key).UnreadCount
4670                al += _statuses.Tabs(key).AllCount
4671            Next
4672        End If
4673
4674        If SettingDialog.DispUsername Then ttl.Append(_username).Append(" - ")
4675        ttl.Append("Tween  ")
4676        Select Case SettingDialog.DispLatestPost
4677            Case DispTitleEnum.Ver
4678                ttl.Append("Ver:").Append(myVer)
4679            Case DispTitleEnum.Post
4680                If _history IsNot Nothing AndAlso _history.Count > 1 Then
4681                    ttl.Append(_history(_history.Count - 2).Replace(vbCrLf, ""))
4682                End If
4683            Case DispTitleEnum.UnreadRepCount
4684                ttl.AppendFormat(My.Resources.SetMainWindowTitleText1, _statuses.Tabs(DEFAULTTAB.REPLY).UnreadCount + _statuses.Tabs(DEFAULTTAB.DM).UnreadCount)
4685            Case DispTitleEnum.UnreadAllCount
4686                ttl.AppendFormat(My.Resources.SetMainWindowTitleText2, ur)
4687            Case DispTitleEnum.UnreadAllRepCount
4688                ttl.AppendFormat(My.Resources.SetMainWindowTitleText3, ur, _statuses.Tabs(DEFAULTTAB.REPLY).UnreadCount + _statuses.Tabs(DEFAULTTAB.DM).UnreadCount)
4689            Case DispTitleEnum.UnreadCountAllCount
4690                ttl.AppendFormat(My.Resources.SetMainWindowTitleText4, ur, al)
4691        End Select
4692
4693        Me.Text = ttl.ToString()
4694    End Sub
4695
4696    Private Sub SetStatusLabel()
4697        'ステータス欄にカウント表示
4698        'タブ未読数/タブ発言数 全未読数/総発言数 (未読@+未読DM数)
4699        Dim urat As Integer = _statuses.Tabs(DEFAULTTAB.REPLY).UnreadCount + _statuses.Tabs(DEFAULTTAB.DM).UnreadCount
4700        Dim ur As Integer = 0
4701        Dim al As Integer = 0
4702        Dim tur As Integer = 0
4703        Dim tal As Integer = 0
4704        Dim slbl As StringBuilder = New StringBuilder(256)
4705        For Each key As String In _statuses.Tabs.Keys
4706            ur += _statuses.Tabs(key).UnreadCount
4707            al += _statuses.Tabs(key).AllCount
4708            If key.Equals(_curTab.Text) Then
4709                tur = _statuses.Tabs(key).UnreadCount
4710                tal = _statuses.Tabs(key).AllCount
4711            End If
4712        Next
4713
4714        slbl.AppendFormat(My.Resources.SetStatusLabelText1, tur, tal, ur, al, urat, _postTimestamps.Count, _favTimestamps.Count, _tlCount)
4715        If SettingDialog.TimelinePeriodInt = 0 Then
4716            slbl.Append(My.Resources.SetStatusLabelText2)
4717        Else
4718            slbl.Append((TimerTimeline.Interval / 1000).ToString() + My.Resources.SetStatusLabelText3)
4719        End If
4720        If Twitter.RemainCountApi > -1 AndAlso SettingDialog.UseAPI Then
4721            slbl.Append(" [API: " + Twitter.RemainCountApi.ToString + "]")
4722        End If
4723
4724        StatusLabelUrl.Text = slbl.ToString()
4725    End Sub
4726
4727    Private Sub SetNotifyIconText()
4728        ' タスクトレイアイコンのツールチップテキスト書き換え
4729        If SettingDialog.DispUsername Then
4730            NotifyIcon1.Text = _username + " - Tween"
4731        Else
4732            NotifyIcon1.Text = "Tween"
4733        End If
4734    End Sub
4735
4736    Friend Sub CheckReplyTo(ByVal StatusText As String)
4737        ' 本当にリプライ先指定すべきかどうかの判定
4738        Dim id As New Regex("(^|[ -/:-@[-^`{-~])@[a-zA-Z0-9_]+")
4739        Dim m As MatchCollection
4740
4741        ' リプライ先ステータスIDの指定がない場合は指定しない
4742        If _reply_to_id = 0 Then Exit Sub
4743
4744        ' リプライ先ユーザー名がない場合も指定しない
4745        If _reply_to_name Is Nothing Then
4746            _reply_to_id = 0
4747            Exit Sub
4748        End If
4749
4750        m = id.Matches(StatusText)
4751
4752        ' 通常Reply
4753        ' 次の条件を満たす場合に in_reply_to_status_id 指定
4754        ' 1. Twitterによりリンクと判定される @idが文中に1つ含まれる (2009/5/28 リンク化される@IDのみカウントするように修正)
4755        ' 2. リプライ先ステータスIDが設定されている(リストをダブルクリックで返信している)
4756        ' 3. 文中に含まれた@idがリプライ先のポスト者のIDと一致する
4757
4758        If m IsNot Nothing AndAlso m.Count = 1 AndAlso m.Item(0).Value = "@" + _reply_to_name AndAlso Not StatusText.StartsWith(". ") Then
4759            Exit Sub
4760        End If
4761
4762        _reply_to_id = 0
4763        _reply_to_name = Nothing
4764
4765    End Sub
4766
4767    Private Sub TweenMain_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Resize
4768        If SettingDialog.MinimizeToTray AndAlso WindowState = FormWindowState.Minimized Then
4769            Me.Visible = False
4770        End If
4771    End Sub
4772
4773    Private Sub PlaySoundMenuItem_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PlaySoundMenuItem.CheckedChanged
4774        If PlaySoundMenuItem.Checked Then
4775            SettingDialog.PlaySound = True
4776        Else
4777            SettingDialog.PlaySound = False
4778        End If
4779    End Sub
4780
4781    Private Sub SplitContainer1_SplitterMoved(ByVal sender As Object, ByVal e As System.Windows.Forms.SplitterEventArgs) Handles SplitContainer1.SplitterMoved
4782        If Me.WindowState = FormWindowState.Normal Then
4783            _mySpDis = SplitContainer1.SplitterDistance
4784            If StatusText.Multiline Then _mySpDis2 = StatusText.Height
4785        End If
4786    End Sub
4787
4788    Private Sub RepliedStatusOpenMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RepliedStatusOpenMenuItem.Click
4789        If _curPost IsNot Nothing AndAlso _curPost.InReplyToUser IsNot Nothing AndAlso _curPost.InReplyToId > 0 Then
4790
4791            OpenUriAsync("http://twitter.com/" + _curPost.InReplyToUser + "/statuses/" + _curPost.InReplyToId.ToString())
4792        End If
4793    End Sub
4794
4795    Private Sub ContextMenuStrip3_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip3.Opening
4796        '発言詳細のアイコン右クリック時のメニュー制御
4797        If _curList.SelectedIndices.Count > 0 AndAlso _curPost IsNot Nothing Then
4798            Dim name As String = _curPost.ImageUrl
4799            If name.Length > 0 Then
4800                name = IO.Path.GetFileNameWithoutExtension(name.Substring(name.LastIndexOf("/"c)))
4801                name = name.Substring(0, name.Length - 7) ' "_normal".Length
4802                Me.IconNameToolStripMenuItem.Enabled = True
4803                If Me.TIconDic.ContainsKey(_curPost.ImageUrl) AndAlso Me.TIconDic(_curPost.ImageUrl) IsNot Nothing Then
4804                    Me.SaveIconPictureToolStripMenuItem.Enabled = True
4805                Else
4806                    Me.SaveIconPictureToolStripMenuItem.Enabled = False
4807                End If
4808                Me.IconNameToolStripMenuItem.Text = name
4809            Else
4810                Me.IconNameToolStripMenuItem.Enabled = False
4811                Me.SaveIconPictureToolStripMenuItem.Enabled = False
4812                Me.IconNameToolStripMenuItem.Text = My.Resources.ContextMenuStrip3_OpeningText1
4813            End If
4814        Else
4815            Me.IconNameToolStripMenuItem.Enabled = False
4816            Me.SaveIconPictureToolStripMenuItem.Enabled = False
4817            Me.IconNameToolStripMenuItem.Text = My.Resources.ContextMenuStrip3_OpeningText2
4818        End If
4819    End Sub
4820
4821    Private Sub IconNameToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IconNameToolStripMenuItem.Click
4822        If _curPost Is Nothing Then Exit Sub
4823        Dim name As String = _curPost.ImageUrl
4824        OpenUriAsync(name.Remove(name.LastIndexOf("_normal"), 7)) ' "_normal".Length
4825    End Sub
4826
4827    Private Sub SaveOriginalSizeIconPictureToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
4828        If _curPost Is Nothing Then Exit Sub
4829        Dim name As String = _curPost.ImageUrl
4830        name = IO.Path.GetFileNameWithoutExtension(name.Substring(name.LastIndexOf("/"c)))
4831
4832        Me.SaveFileDialog1.FileName = name.Substring(0, name.Length - 8) ' "_normal".Length + 1
4833
4834        If Me.SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
4835            ' STUB
4836        End If
4837    End Sub
4838
4839    Private Sub SaveIconPictureToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveIconPictureToolStripMenuItem.Click
4840        If _curPost Is Nothing Then Exit Sub
4841        Dim name As String = _curPost.ImageUrl
4842
4843        Me.SaveFileDialog1.FileName = name.Substring(name.LastIndexOf("/"c) + 1)
4844
4845        If Me.SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
4846            Using bmp2 As New Bitmap(TIconDic(name).Size.Width, TIconDic(name).Size.Height)
4847                Using g As Graphics = Graphics.FromImage(bmp2)
4848                    g.InterpolationMode = Drawing2D.InterpolationMode.High
4849                    g.DrawImage(TIconDic(name), 0, 0, TIconDic(name).Size.Width, TIconDic(name).Size.Height)
4850                End Using
4851                bmp2.Save(Me.SaveFileDialog1.FileName)
4852            End Using
4853        End If
4854    End Sub
4855
4856    Private Sub SplitContainer2_Panel2_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SplitContainer2.Panel2.Resize
4857        Me.StatusText.Multiline = Me.SplitContainer2.Panel2.Height > Me.SplitContainer2.Panel2MinSize + 2
4858        MultiLineMenuItem.Checked = Me.StatusText.Multiline
4859    End Sub
4860
4861    Private Sub StatusText_MultilineChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StatusText.MultilineChanged
4862        If Me.StatusText.Multiline Then
4863            Me.StatusText.ScrollBars = ScrollBars.Vertical
4864        Else
4865            Me.StatusText.ScrollBars = ScrollBars.None
4866        End If
4867    End Sub
4868
4869    Private Sub MultiLineMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MultiLineMenuItem.Click
4870        '発言欄複数行
4871        StatusText.Multiline = MultiLineMenuItem.Checked
4872        _cfgLocal.StatusMultiline = MultiLineMenuItem.Checked
4873        If MultiLineMenuItem.Checked Then
4874            If SplitContainer2.Height - _mySpDis2 - SplitContainer2.SplitterWidth < 0 Then
4875                SplitContainer2.SplitterDistance = 0
4876            Else
4877                SplitContainer2.SplitterDistance = SplitContainer2.Height - _mySpDis2 - SplitContainer2.SplitterWidth
4878            End If
4879        Else
4880            SplitContainer2.SplitterDistance = SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth
4881        End If
4882    End Sub
4883
4884    Private Function UrlConvert(ByVal Converter_Type As UrlConverter) As Boolean
4885        Dim result As String = ""
4886        Dim url As Regex = New Regex("(?<![0-9A-Za-z])(?:https?|shttp)://(?:(?:[-_.!~*'()a-zA-Z0-9;:&=+$,]|%[0-9A-Fa-f" + _
4887                                     "][0-9A-Fa-f])*@)?(?:(?:[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?\.)" + _
4888                                     "*[a-zA-Z](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?\.?|[0-9]+\.[0-9]+\.[0-9]+\." + _
4889                                     "[0-9]+)(?::[0-9]*)?(?:/(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f]" + _
4890                                     "[0-9A-Fa-f])*(?:;(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-" + _
4891                                     "Fa-f])*)*(?:/(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f" + _
4892                                     "])*(?:;(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)*)" + _
4893                                     "*)?(?:\?(?:[-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])" + _
4894                                     "*)?(?:#(?:[-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)?")
4895
4896
4897        If StatusText.SelectionLength > 0 Then
4898            Dim tmp As String = StatusText.SelectedText
4899            ' httpから始まらない場合、ExcludeStringで指定された文字列で始まる場合は対象としない
4900            If tmp.StartsWith("http") Then
4901                ' 文字列が選択されている場合はその文字列について処理
4902
4903                '短縮URL変換 日本語を含むかもしれないのでURLエンコードする
4904                result = Twitter.MakeShortUrl(Converter_Type, StatusText.SelectedText)
4905
4906                If result.Equals("Can't convert") Then
4907                    StatusLabel.Text = result.Insert(0, Converter_Type.ToString() + ":")
4908                    Return False
4909                End If
4910
4911                If Not result = "" Then
4912                    Dim undotmp As New urlUndo
4913
4914                    StatusText.Select(StatusText.Text.IndexOf(tmp, StringComparison.Ordinal), tmp.Length)
4915                    StatusText.SelectedText = result
4916
4917                    'undoバッファにセット
4918                    undotmp.Before = tmp
4919                    undotmp.After = result
4920
4921                    If urlUndoBuffer Is Nothing Then
4922                        urlUndoBuffer = New List(Of urlUndo)
4923                        UrlUndoToolStripMenuItem.Enabled = True
4924                    End If
4925
4926                    urlUndoBuffer.Add(undotmp)
4927                End If
4928            End If
4929        Else
4930            Dim urls As RegularExpressions.MatchCollection = Nothing
4931            urls = url.Matches(StatusText.Text)
4932
4933            ' 正規表現にマッチしたURL文字列をtinyurl化
4934            For Each tmp2 As Match In urls
4935                Dim tmp As String = tmp2.ToString
4936                Dim undotmp As New urlUndo
4937
4938                '選んだURLを選択(?)
4939                StatusText.Select(StatusText.Text.IndexOf(tmp, StringComparison.Ordinal), tmp.Length)
4940
4941                '短縮URL変換
4942                result = Twitter.MakeShortUrl(Converter_Type, StatusText.SelectedText)
4943
4944                If result.Equals("Can't convert") Then
4945                    StatusLabel.Text = result.Insert(0, Converter_Type.ToString() + ":")
4946                    Return False
4947                End If
4948
4949                If Not result = "" Then
4950                    StatusText.Select(StatusText.Text.IndexOf(tmp, StringComparison.Ordinal), tmp.Length)
4951                    StatusText.SelectedText = result
4952                    'undoバッファにセット
4953                    undotmp.Before = tmp
4954                    undotmp.After = result
4955
4956                    If urlUndoBuffer Is Nothing Then
4957                        urlUndoBuffer = New List(Of urlUndo)
4958                        UrlUndoToolStripMenuItem.Enabled = True
4959                    End If
4960
4961                    urlUndoBuffer.Add(undotmp)
4962                End If
4963            Next
4964        End If
4965
4966        Return True
4967
4968    End Function
4969
4970    Private Sub doUrlUndo()
4971        If urlUndoBuffer IsNot Nothing Then
4972            Dim tmp As String = StatusText.Text
4973            For Each data As urlUndo In urlUndoBuffer
4974                tmp = tmp.Replace(data.After, data.Before)
4975            Next
4976            StatusText.Text = tmp
4977            urlUndoBuffer = Nothing
4978            UrlUndoToolStripMenuItem.Enabled = False
4979        End If
4980    End Sub
4981
4982    Private Sub TinyURLToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TinyURLToolStripMenuItem.Click
4983        UrlConvert(UrlConverter.TinyUrl)
4984    End Sub
4985
4986    Private Sub IsgdToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IsgdToolStripMenuItem.Click
4987        UrlConvert(UrlConverter.Isgd)
4988    End Sub
4989
4990    Private Sub TwurlnlToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TwurlnlToolStripMenuItem.Click
4991        UrlConvert(UrlConverter.Twurl)
4992    End Sub
4993
4994    Private Sub UrlConvertAutoToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UrlConvertAutoToolStripMenuItem.Click
4995        If Not UrlConvert(SettingDialog.AutoShortUrlFirst) Then
4996            Dim svc As UrlConverter = SettingDialog.AutoShortUrlFirst
4997            Dim rnd As New Random()
4998            ' 前回使用した短縮URLサービス以外を選択する
4999            Do
5000                svc = CType(rnd.Next(System.Enum.GetNames(GetType(UrlConverter)).Length), UrlConverter)
5001            Loop Until svc <> SettingDialog.AutoShortUrlFirst
5002            UrlConvert(svc)
5003        End If
5004    End Sub
5005
5006    Private Sub UrlUndoToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UrlUndoToolStripMenuItem.Click
5007        doUrlUndo()
5008    End Sub
5009
5010    Private Sub NewPostPopMenuItem_CheckStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles NewPostPopMenuItem.CheckStateChanged
5011        _cfgCommon.NewAllPop = NewPostPopMenuItem.Checked
5012    End Sub
5013
5014    Private Sub ListLockMenuItem_CheckStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListLockMenuItem.CheckStateChanged
5015        _cfgCommon.ListLock = ListLockMenuItem.Checked
5016    End Sub
5017
5018    Private Sub MenuStrip1_MenuActivate(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuStrip1.MenuActivate
5019        ' フォーカスがメニューに移る (MenuStrip1.Tag フラグを立てる)
5020        MenuStrip1.Tag = New Object()
5021        MenuStrip1.Select() ' StatusText がフォーカスを持っている場合 Leave が発生
5022    End Sub
5023
5024    Private Sub MenuStrip1_MenuDeactivate(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuStrip1.MenuDeactivate
5025        If Me.Tag IsNot Nothing Then ' 設定された戻り先へ遷移
5026            DirectCast(Me.Tag, Control).Select()
5027        Else ' 戻り先が指定されていない (初期状態) 場合はタブに遷移
5028            If ListTab.SelectedIndex > -1 AndAlso ListTab.SelectedTab.HasChildren Then
5029                Me.Tag = ListTab.SelectedTab.Controls(0)
5030                DirectCast(Me.Tag, Control).Select()
5031            End If
5032        End If
5033        ' フォーカスがメニューに遷移したかどうかを表すフラグを降ろす
5034        MenuStrip1.Tag = Nothing
5035    End Sub
5036
5037    Private Sub MyList_ColumnReordered(ByVal sender As System.Object, ByVal e As ColumnReorderedEventArgs)
5038        Dim lst As DetailsListView = DirectCast(sender, DetailsListView)
5039        If _cfgLocal Is Nothing Then Exit Sub
5040
5041        If _iconCol Then
5042            _cfgLocal.Width1 = lst.Columns(0).Width
5043            _cfgLocal.Width3 = lst.Columns(1).Width
5044        Else
5045            Dim darr(lst.Columns.Count - 1) As Integer
5046            For i As Integer = 0 To lst.Columns.Count - 1
5047                darr(lst.Columns(i).DisplayIndex) = i
5048            Next
5049            MoveArrayItem(darr, e.OldDisplayIndex, e.NewDisplayIndex)
5050
5051            For i As Integer = 0 To lst.Columns.Count - 1
5052                Select Case darr(i)
5053                    Case 0
5054                        _cfgLocal.DisplayIndex1 = i
5055                    Case 1
5056                        _cfgLocal.DisplayIndex2 = i
5057                    Case 2
5058                        _cfgLocal.DisplayIndex3 = i
5059                    Case 3
5060                        _cfgLocal.DisplayIndex4 = i
5061                    Case 4
5062                        _cfgLocal.DisplayIndex5 = i
5063                    Case 5
5064                        _cfgLocal.DisplayIndex6 = i
5065                    Case 6
5066                        _cfgLocal.DisplayIndex7 = i
5067                    Case 7
5068                        _cfgLocal.DisplayIndex8 = i
5069                End Select
5070            Next
5071            _cfgLocal.Width1 = lst.Columns(0).Width
5072            _cfgLocal.Width2 = lst.Columns(1).Width
5073            _cfgLocal.Width3 = lst.Columns(2).Width
5074            _cfgLocal.Width4 = lst.Columns(3).Width
5075            _cfgLocal.Width5 = lst.Columns(4).Width
5076            _cfgLocal.Width6 = lst.Columns(5).Width
5077            _cfgLocal.Width7 = lst.Columns(6).Width
5078            _cfgLocal.Width8 = lst.Columns(7).Width
5079        End If
5080        SaveConfigsLocal()
5081    End Sub
5082
5083    Private Sub MyList_ColumnWidthChanged(ByVal sender As System.Object, ByVal e As ColumnWidthChangedEventArgs)
5084        Dim lst As DetailsListView = DirectCast(sender, DetailsListView)
5085        Dim changed As Boolean = False
5086        If _cfgLocal Is Nothing Then Exit Sub
5087        If _iconCol Then
5088            If _cfgLocal.Width1 <> lst.Columns(0).Width Then
5089                _cfgLocal.Width1 = lst.Columns(0).Width
5090                changed = True
5091            End If
5092            If _cfgLocal.Width3 <> lst.Columns(1).Width Then
5093                _cfgLocal.Width3 = lst.Columns(1).Width
5094                changed = True
5095            End If
5096        Else
5097            If _cfgLocal.Width1 <> lst.Columns(0).Width Then
5098                _cfgLocal.Width1 = lst.Columns(0).Width
5099                changed = True
5100            End If
5101            If _cfgLocal.Width2 <> lst.Columns(1).Width Then
5102                _cfgLocal.Width2 = lst.Columns(1).Width
5103                changed = True
5104            End If
5105            If _cfgLocal.Width3 <> lst.Columns(2).Width Then
5106                _cfgLocal.Width3 = lst.Columns(2).Width
5107                changed = True
5108            End If
5109            If _cfgLocal.Width4 <> lst.Columns(3).Width Then
5110                _cfgLocal.Width4 = lst.Columns(3).Width
5111                changed = True
5112            End If
5113            If _cfgLocal.Width5 <> lst.Columns(4).Width Then
5114                _cfgLocal.Width5 = lst.Columns(4).Width
5115                changed = True
5116            End If
5117            If _cfgLocal.Width6 <> lst.Columns(5).Width Then
5118                _cfgLocal.Width6 = lst.Columns(5).Width
5119                changed = True
5120            End If
5121            If _cfgLocal.Width7 <> lst.Columns(6).Width Then
5122                _cfgLocal.Width7 = lst.Columns(6).Width
5123                changed = True
5124            End If
5125            If _cfgLocal.Width8 <> lst.Columns(7).Width Then
5126                _cfgLocal.Width8 = lst.Columns(7).Width
5127                changed = True
5128            End If
5129        End If
5130        ' 非表示の時にColumnChangedが呼ばれた場合はForm初期化処理中なので保存しない
5131        If changed Then
5132            SaveConfigsLocal()
5133        End If
5134    End Sub
5135
5136    Private Sub ToolStripMenuItem3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem3.Click
5137        '発言詳細で「選択文字列をコピー」
5138        'PostBrowser.Document.ExecCommand("Copy", False, Nothing)
5139        'SendKeys.Send("^c")
5140        Dim typ As Type = PostBrowser.ActiveXInstance.GetType()
5141        Dim _SelObj As Object = typ.InvokeMember("selection", BindingFlags.GetProperty, Nothing, PostBrowser.Document.DomDocument, Nothing)
5142        Dim _objRange As Object = _SelObj.GetType().InvokeMember("createRange", BindingFlags.InvokeMethod, Nothing, _SelObj, Nothing)
5143        Dim _selText As String = DirectCast(_objRange.GetType().InvokeMember("text", BindingFlags.GetProperty, Nothing, _objRange, Nothing), String)
5144        Clipboard.SetDataObject(_selText, False, 5, 100)
5145    End Sub
5146
5147    Private Sub doSearchToolStrip(ByVal url As String)
5148        '発言詳細で「選択文字列で検索」(選択文字列取得)
5149        Dim typ As Type = PostBrowser.ActiveXInstance.GetType()
5150        Dim _SelObj As Object = typ.InvokeMember("selection", BindingFlags.GetProperty, Nothing, PostBrowser.Document.DomDocument, Nothing)
5151        Dim _objRange As Object = _SelObj.GetType().InvokeMember("createRange", BindingFlags.InvokeMethod, Nothing, _SelObj, Nothing)
5152        Dim _selText As String = DirectCast(_objRange.GetType().InvokeMember("text", BindingFlags.GetProperty, Nothing, _objRange, Nothing), String)
5153        Dim tmp As String
5154
5155        If _selText IsNot Nothing Then
5156            tmp = String.Format(url, HttpUtility.UrlEncode(_selText))
5157            OpenUriAsync(tmp)
5158        End If
5159    End Sub
5160
5161    Private Sub ToolStripMenuItem5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem5.Click
5162        '発言詳細ですべて選択
5163        PostBrowser.Document.ExecCommand("SelectAll", False, Nothing)
5164    End Sub
5165
5166    Private Sub SearchItem1ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchItem1ToolStripMenuItem.Click
5167        doSearchToolStrip(My.Resources.SearchItem1Url)
5168    End Sub
5169
5170    Private Sub SearchItem2ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchItem2ToolStripMenuItem.Click
5171        doSearchToolStrip(My.Resources.SearchItem2Url)
5172    End Sub
5173
5174    Private Sub SearchItem3ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchItem3ToolStripMenuItem.Click
5175        doSearchToolStrip(My.Resources.SearchItem3Url)
5176    End Sub
5177
5178    Private Sub SearchItem4ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchItem4ToolStripMenuItem.Click
5179        doSearchToolStrip(My.Resources.SearchItem4Url)
5180    End Sub
5181
5182    Private Sub ToolStripMenuItem4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem4.Click
5183        'URLをコピー
5184        'If PostBrowser.StatusText.StartsWith("http") Then   '念のため
5185        Clipboard.SetDataObject(PostBrowser.StatusText, False, 5, 100)
5186        'End If
5187    End Sub
5188
5189    Private Sub ContextMenuStrip4_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip4.Opening
5190        ' URLコピーの項目の表示/非表示
5191        If PostBrowser.StatusText.StartsWith("http") Then
5192            ToolStripMenuItem4.Enabled = True
5193        Else
5194            ToolStripMenuItem4.Enabled = False
5195        End If
5196        ' 文字列選択されていないときは選択文字列関係の項目を非表示に
5197        Dim _selText As String = PostBrowser_GetSelectionText()
5198        If _selText Is Nothing Then
5199            ToolStripMenuItem2.Enabled = False
5200            ToolStripMenuItem3.Enabled = False
5201        Else
5202            ToolStripMenuItem2.Enabled = True
5203            ToolStripMenuItem3.Enabled = True
5204        End If
5205        e.Cancel = False
5206    End Sub
5207
5208    Private Function PostBrowser_GetSelectionText() As String
5209        Dim typ As Type = PostBrowser.ActiveXInstance.GetType()
5210        Dim _SelObj As Object = typ.InvokeMember("selection", BindingFlags.GetProperty, Nothing, PostBrowser.Document.DomDocument, Nothing)
5211        Dim _objRange As Object = _SelObj.GetType().InvokeMember("createRange", BindingFlags.InvokeMethod, Nothing, _SelObj, Nothing)
5212        Return DirectCast(_objRange.GetType().InvokeMember("text", BindingFlags.GetProperty, Nothing, _objRange, Nothing), String)
5213    End Function
5214
5215    Private Sub CurrentTabToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CurrentTabToolStripMenuItem.Click
5216        '発言詳細の選択文字列で現在のタブを検索
5217        Dim _selText As String = PostBrowser_GetSelectionText()
5218
5219        If _selText IsNot Nothing Then
5220            SearchDialog.SWord = _selText
5221            SearchDialog.CheckCaseSensitive = False
5222            SearchDialog.CheckRegex = False
5223
5224            DoTabSearch(SearchDialog.SWord, _
5225                        SearchDialog.CheckCaseSensitive, _
5226                        SearchDialog.CheckRegex, _
5227                        SEARCHTYPE.NextSearch)
5228        End If
5229    End Sub
5230
5231    Private Sub SplitContainer2_SplitterMoved(ByVal sender As Object, ByVal e As System.Windows.Forms.SplitterEventArgs) Handles SplitContainer2.SplitterMoved
5232        If StatusText.Multiline Then _mySpDis2 = StatusText.Height
5233    End Sub
5234
5235    Private Sub TweenMain_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragDrop
5236        Dim data As String = TryCast(e.Data.GetData(DataFormats.StringFormat, True), String)
5237        If data IsNot Nothing Then
5238            StatusText.Text += data
5239        End If
5240    End Sub
5241
5242    Private Sub TweenMain_DragOver(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragOver
5243        Dim data As String = TryCast(e.Data.GetData(DataFormats.StringFormat, True), String)
5244        If data IsNot Nothing Then
5245            e.Effect = DragDropEffects.Copy
5246        Else
5247            e.Effect = DragDropEffects.None
5248        End If
5249    End Sub
5250
5251    ' Contributed by shuyoko <http://twitter.com/shuyoko> BEGIN:
5252    Private Sub BlackFavAddToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BlackFavAddToolStripMenuItem.Click
5253
5254        Dim cnt As Integer = 0
5255        'Dim MyList As DetailsListView = DirectCast(ListTab.SelectedTab.Controls(0), DetailsListView)
5256
5257        If _curTab.Text = DEFAULTTAB.DM OrElse _curList.SelectedIndices.Count = 0 Then Exit Sub
5258
5259        If _curList.SelectedIndices.Count > 1 Then
5260            If MessageBox.Show(My.Resources.BlackFavAddToolStripMenuItem_ClickText1, My.Resources.BlackFavAddToolStripMenuItem_ClickText2, _
5261                               MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
5262                Exit Sub
5263            End If
5264        End If
5265
5266        Dim args As New GetWorkerArg()
5267        args.ids = New List(Of Long)
5268        args.sIds = New List(Of Long)
5269        args.tName = _curTab.Text
5270        For Each idx As Integer In _curList.SelectedIndices
5271            If Not _statuses.Item(_curTab.Text, idx).IsFav Then
5272                args.ids.Add(_statuses.Item(_curTab.Text, idx).Id)
5273            End If
5274        Next
5275        args.type = WORKERTYPE.BlackFavAdd
5276        If args.ids.Count = 0 Then
5277            StatusLabel.Text = My.Resources.BlackFavAddToolStripMenuItem_ClickText4
5278            Exit Sub
5279        End If
5280
5281        RunAsync(args)
5282    End Sub
5283
5284    Private Function IsNetworkAvailable() As Boolean
5285        Dim nw As Boolean = True
5286        Try
5287            nw = My.Computer.Network.IsAvailable
5288        Catch ex As Exception
5289            nw = True
5290        End Try
5291        Return nw
5292    End Function
5293
5294    Private Sub OpenUriAsync(ByVal UriString As String)
5295        Dim args As New GetWorkerArg
5296        args.type = WORKERTYPE.OpenUri
5297        args.status = UriString
5298
5299        RunAsync(args)
5300    End Sub
5301
5302    Private Sub ListTabSelect(ByVal _tab As TabPage)
5303        SetListProperty()
5304
5305        _itemCache = Nothing
5306        _itemCacheIndex = -1
5307        _postCache = Nothing
5308        _curTab = _tab
5309        _curList = DirectCast(_tab.Controls(0), DetailsListView)
5310        If _curList.SelectedIndices.Count > 0 Then
5311            _curItemIndex = _curList.SelectedIndices(0)
5312            _curPost = GetCurTabPost(_curItemIndex)
5313        Else
5314            _curItemIndex = -1
5315            _curPost = Nothing
5316        End If
5317
5318        _anchorPost = Nothing
5319        _anchorFlag = False
5320    End Sub
5321
5322    Private Sub ListTab_Selecting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TabControlCancelEventArgs) Handles ListTab.Selecting
5323        ListTabSelect(e.TabPage)
5324    End Sub
5325
5326    Private Sub SelectListItem(ByVal LView As DetailsListView, ByVal Index As Integer)
5327        '単一
5328        Dim bnd As Rectangle
5329        Dim flg As Boolean = False
5330        If LView.FocusedItem IsNot Nothing Then
5331            bnd = LView.FocusedItem.Bounds
5332            flg = True
5333        End If
5334
5335        LView.SelectedIndices.Clear()
5336        LView.Items(Index).Selected = True
5337        LView.Items(Index).Focused = True
5338        If flg Then LView.Invalidate(bnd)
5339    End Sub
5340
5341    Private Sub SelectListItem(ByVal LView As DetailsListView, ByVal Index() As Integer, ByVal FocusedIndex As Integer)
5342        '複数
5343        Dim bnd As Rectangle
5344        Dim flg As Boolean = False
5345        If LView.FocusedItem IsNot Nothing Then
5346            bnd = LView.FocusedItem.Bounds
5347            flg = True
5348        End If
5349
5350        If Index IsNot Nothing AndAlso Index(0) > -1 Then
5351            LView.SelectedIndices.Clear()
5352            For Each idx As Integer In Index
5353                LView.SelectedIndices.Add(idx)
5354            Next
5355        End If
5356        If FocusedIndex > -1 Then
5357            LView.Items(FocusedIndex).Focused = True
5358        End If
5359        If flg Then LView.Invalidate(bnd)
5360    End Sub
5361
5362    Private Sub RunAsync(ByVal args As GetWorkerArg)
5363        Dim bw As BackgroundWorker = Nothing
5364        For i As Integer = 0 To _bw.Length - 1
5365            If _bw(i) IsNot Nothing AndAlso Not _bw(i).IsBusy Then
5366                bw = _bw(i)
5367                Exit For
5368            End If
5369        Next
5370        If bw Is Nothing Then
5371            For i As Integer = 0 To _bw.Length - 1
5372                If _bw(i) Is Nothing Then
5373                    _bw(i) = New BackgroundWorker
5374                    bw = _bw(i)
5375                    bw.WorkerReportsProgress = True
5376                    bw.WorkerSupportsCancellation = True
5377                    AddHandler bw.DoWork, AddressOf GetTimelineWorker_DoWork
5378                    AddHandler bw.ProgressChanged, AddressOf GetTimelineWorker_ProgressChanged
5379                    AddHandler bw.RunWorkerCompleted, AddressOf GetTimelineWorker_RunWorkerCompleted
5380                    Exit For
5381                End If
5382            Next
5383        End If
5384        If bw Is Nothing Then Exit Sub
5385
5386        bw.RunWorkerAsync(args)
5387    End Sub
5388
5389    Private Sub TweenMain_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
5390        If IsNetworkAvailable() Then
5391            If SettingDialog.ReadPages > 0 Then
5392                _waitTimeline = True
5393                GetTimeline(WORKERTYPE.Timeline, 1, SettingDialog.ReadPages)
5394            End If
5395            If SettingDialog.ReadPagesReply > 0 Then
5396                _waitReply = True
5397                GetTimeline(WORKERTYPE.Reply, 1, SettingDialog.ReadPagesReply)
5398            End If
5399            If SettingDialog.ReadPagesDM > 0 Then
5400                _waitDm = True
5401                GetTimeline(WORKERTYPE.DirectMessegeRcv, 1, SettingDialog.ReadPagesDM)
5402            End If
5403            Dim i As Integer = 0
5404            Do While (_waitTimeline OrElse _waitReply OrElse _waitDm) AndAlso Not _endingFlag
5405                System.Threading.Thread.Sleep(100)
5406                My.Application.DoEvents()
5407                i += 1
5408                If i > 50 Then
5409                    If Not _endingFlag Then
5410                        _statuses.DistributePosts()
5411                        RefreshTimeline()
5412                    Else
5413                        Exit Sub
5414                    End If
5415                    i = 0
5416                End If
5417            Loop
5418
5419            If _endingFlag Then Exit Sub
5420
5421            _statuses.DistributePosts()
5422            RefreshTimeline()
5423
5424            'バージョンチェック(引数:起動時チェックの場合はTrue・・・チェック結果のメッセージを表示しない)
5425            If SettingDialog.StartupVersion Then
5426                CheckNewVersion(True)
5427            End If
5428
5429            ' APIモードで起動した場合に警告する
5430            If Not SettingDialog.StartupAPImodeNoWarning AndAlso SettingDialog.UseAPI Then
5431                If MessageBox.Show("現在APIモードです。APIモードではタイムライン取得に回数制限があり、制限回数を超えるとタイムライン取得が行えなくなります。この制限について理解していますか?Web取得モードではタイムライン取得にAPIを使用せず、API回数制限の影響を受けません。Web取得モードに切り替える場合は「OK」を押してください。", "警告", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) = Windows.Forms.DialogResult.OK Then
5432                    SettingDialog.UseAPI = False
5433                    SaveConfigsCommon()
5434                    MessageBox.Show("APIモードをオフにし、Web取得モードへ切り替えました。")
5435                Else
5436                    MessageBox.Show("APIモードを維持することを選択しました。Web取得に戻す場合は設定の動作タブにある「API使用」のチェックを外すと戻すことができます。" + Environment.NewLine + Environment.NewLine + "※APIモードの制限を理解された方のみ、次回より警告を表示しないよう設定画面で変更してください※")
5437                    MessageBox.Show("取得間隔に注意してください。タイムライン取得系APIはRecent,Reply,DMの合計で1時間に" + GetMaxCountApi.ToString() + "回までしか使えません。", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning)
5438                End If
5439            End If
5440
5441        Else
5442            TimerRefreshIcon.Enabled = False
5443            NotifyIcon1.Icon = NIconAtSmoke
5444            PostButton.Enabled = False
5445            FavAddToolStripMenuItem.Enabled = False
5446            FavRemoveToolStripMenuItem.Enabled = False
5447            MoveToHomeToolStripMenuItem.Enabled = False
5448            MoveToFavToolStripMenuItem.Enabled = False
5449            DeleteStripMenuItem.Enabled = False
5450            RefreshStripMenuItem.Enabled = False
5451        End If
5452        _initial = False
5453    End Sub
5454
5455    Private Sub doGetFollowersMenu(ByVal CacheInvalidate As Boolean)
5456        Try
5457            StatusLabel.Text = My.Resources.UpdateFollowersMenuItem1_ClickText1
5458            My.Application.DoEvents()
5459            Me.Cursor = Cursors.WaitCursor
5460            Dim ret As String
5461            If SettingDialog.UseAPI Then
5462                ret = Twitter.GetFollowersApi()
5463            Else
5464                ret = Twitter.GetFollowers(CacheInvalidate)
5465            End If
5466            If ret <> "" Then
5467                StatusLabel.Text = My.Resources.UpdateFollowersMenuItem1_ClickText2 & ret
5468                Exit Sub
5469            End If
5470            StatusLabel.Text = My.Resources.UpdateFollowersMenuItem1_ClickText3
5471        Finally
5472            Me.Cursor = Cursors.Default
5473        End Try
5474    End Sub
5475
5476    Private Sub GetFollowersDiffToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GetFollowersDiffToolStripMenuItem.Click
5477        doGetFollowersMenu(False)       ' Followersリストキャッシュ有効
5478    End Sub
5479
5480    Private Sub GetFollowersAllToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GetFollowersAllToolStripMenuItem.Click
5481        doGetFollowersMenu(True)        ' Followersリストキャッシュ無効
5482    End Sub
5483
5484    Private Sub ReTweetStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReTweetStripMenuItem.Click
5485        'RT:内容 (via @id)
5486        If _curPost IsNot Nothing Then
5487            If _curPost.IsDm OrElse SettingDialog.ProtectNotInclude AndAlso _curPost.IsProtect Or _
5488               Not StatusText.Enabled Then Exit Sub
5489
5490            Dim rtdata As String = _curPost.OriginalData
5491            ' Twitterにより省略されているURLを含むaタグをキャプチャしてリンク先URLへ置き換える
5492            Dim rx As Regex = New Regex("<a target=""_self"" href=""(?<url>[^""]+)"" rel=""nofollow"" target=""_blank"">(?<link>[^<]+)</a>")
5493            rtdata = rx.Replace(rtdata, "${url}")
5494
5495            'その他のリンク(@IDなど)を置き換える
5496            rx = New Regex("<a target=""_self"" href=""(?<url>[^""]+)"">(?<link>[^<]+)</a>")
5497            rtdata = rx.Replace(rtdata, "${link}")
5498
5499            '<br>タグ除去
5500            If StatusText.Multiline Then
5501                rtdata = Regex.Replace(rtdata, "(\r\n|\n|\r)<br>", vbCrLf, RegexOptions.IgnoreCase Or RegexOptions.Multiline)
5502            Else
5503                rtdata = Regex.Replace(rtdata, "(\r\n|\n|\r)<br>", "", RegexOptions.IgnoreCase Or RegexOptions.Multiline)
5504            End If
5505
5506            StatusText.Text = "RT @" + _curPost.Name + ": " + rtdata
5507            _reply_to_id = 0
5508            _reply_to_name = Nothing
5509            StatusText.SelectionStart = StatusText.Text.Length
5510            StatusText.Focus()
5511        End If
5512    End Sub
5513
5514    Private Sub DumpPostClassToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DumpPostClassToolStripMenuItem.Click
5515        If _curPost IsNot Nothing Then
5516            DispSelectedPost()
5517        End If
5518    End Sub
5519
5520    Private Sub MenuItemHelp_DropDownOpening(ByVal sender As Object, ByVal e As System.EventArgs) Handles MenuItemHelp.DropDownOpening
5521        If DebugBuild OrElse My.Computer.Keyboard.CapsLock AndAlso My.Computer.Keyboard.CtrlKeyDown AndAlso My.Computer.Keyboard.ShiftKeyDown Then
5522            DebugModeToolStripMenuItem.Visible = True
5523        Else
5524            DebugModeToolStripMenuItem.Visible = False
5525        End If
5526    End Sub
5527
5528    Private Sub ButtonPostMode_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonPostMode.Click
5529        ContextMenuStripPostMode.Show(ButtonPostMode, position:=New Point(0, ButtonPostMode.Height))
5530    End Sub
5531
5532    Private Sub ToolStripMenuItemUrlAutoShorten_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItemUrlAutoShorten.CheckedChanged
5533        SettingDialog.UrlConvertAuto = ToolStripMenuItemUrlAutoShorten.Checked
5534    End Sub
5535
5536    Private Sub ContextMenuStripPostMode_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStripPostMode.Opening
5537        ToolStripMenuItemUrlAutoShorten.Checked = SettingDialog.UrlConvertAuto
5538    End Sub
5539
5540    Private Sub TraceOutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TraceOutToolStripMenuItem.Click
5541        If TraceOutToolStripMenuItem.Checked Then
5542            TraceFlag = True
5543        Else
5544            TraceFlag = False
5545        End If
5546    End Sub
5547
5548    Private Sub TweenMain_Deactivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Deactivate
5549        '画面が非アクティブになったら、発言欄の背景色をデフォルトへ
5550        Me.StatusText_Leave(StatusText, System.EventArgs.Empty)
5551    End Sub
5552
5553    Private Sub TabRenameMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TabRenameMenuItem.Click
5554        TabRename()
5555    End Sub
5556
5557    Private Sub UnuToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UnuToolStripMenuItem.Click
5558        UrlConvert(UrlConverter.Unu)
5559    End Sub
5560
5561    Private Sub BitlyToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BitlyToolStripMenuItem.Click
5562        UrlConvert(UrlConverter.Bitly)
5563    End Sub
5564
5565    Private Sub ApiInfoMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ApiInfoMenuItem.Click
5566        Dim info As New ApiInfo
5567        Dim tmp As String
5568
5569        If GetInfoApi(info) Then
5570            tmp = "1時間あたりの取得系API使用最大回数 " + info.MaxCount.ToString() + "回" + vbCrLf + _
5571                "現在の取得系API使用回数 " + (info.MaxCount - info.RemainCount).ToString + "回" + vbCrLf + _
5572                "あと " + info.RemainCount.ToString + " 回 取得系APIを使用できます" + vbCrLf + _
5573                "使用回数のカウントは " + info.ResetTime.ToString() + "にリセットされます"
5574        Else
5575            tmp = "API情報の取得に失敗しました"
5576        End If
5577        MessageBox.Show(tmp, "API使用回数情報", MessageBoxButtons.OK, MessageBoxIcon.Information)
5578    End Sub
5579
5580End Class
Note: See TracBrowser for help on using the browser.