1 // OpenTween - Client of Twitter
2 // Copyright (c) 2007-2011 kiri_feather (@kiri_feather) <kiri.feather@gmail.com>
3 // (c) 2008-2011 Moz (@syo68k)
4 // (c) 2008-2011 takeshik (@takeshik) <http://www.takeshik.org/>
5 // (c) 2010-2011 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
6 // (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
7 // (c) 2011 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
8 // All rights reserved.
10 // This file is part of OpenTween.
12 // This program is free software; you can redistribute it and/or modify it
13 // under the terms of the GNU General public License as published by the Free
14 // Software Foundation; either version 3 of the License, or (at your option)
17 // This program is distributed in the hope that it will be useful, but
18 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License
22 // You should have received a copy of the GNU General public License along
23 // with this program. if (not, see <http://www.gnu.org/licenses/>, or write to
24 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
25 // Boston, MA 02110-1301, USA.
28 //"c:\Program Files\Microsoft.NET\SDK\v2.0\Bin\sgen.exe" /f /a:"$(TargetPath)"
29 //"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\sgen.exe" /f /a:"$(TargetPath)"
32 using System.Collections.Generic;
33 using System.ComponentModel;
38 using System.Windows.Forms;
39 using OpenTween.OpenTweenCustomControl;
41 using System.Text.RegularExpressions;
42 using System.Reflection;
43 using System.Threading;
46 using System.Diagnostics;
47 using OpenTween.Thumbnail;
48 using System.Threading.Tasks;
54 public partial class TweenMain : Form
57 private Size _mySize; //画面サイズ
58 private Point _myLoc; //画面位置
59 private int _mySpDis; //区切り位置
60 private int _mySpDis2; //発言欄区切り位置
61 private int _mySpDis3; //プレビュー区切り位置
62 private int _myAdSpDis; //Ad区切り位置
63 private int _iconSz; //アイコンサイズ(現在は16、24、48の3種類。将来直接数字指定可能とする 注:24x24の場合に26と指定しているのはMSゴシック系フォントのための仕様)
64 private bool _iconCol; //1列表示の時true(48サイズのとき)
67 private bool _initial; //true:起動時処理中
68 private bool _initialLayout = true;
69 private bool _ignoreConfigSave; //true:起動時処理中
70 private bool _tabDrag; //タブドラッグ中フラグ(DoDragDropを実行するかの判定用)
71 private TabPage _beforeSelectedTab; //タブが削除されたときに前回選択されていたときのタブを選択する為に保持
72 private Point _tabMouseDownPoint;
73 private string _rclickTabName; //右クリックしたタブの名前(Tabコントロール機能不足対応)
74 private readonly object _syncObject = new object(); //ロック用
75 private const string detailHtmlFormatMono1 = "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=8\"><style type=\"text/css\"><!-- pre {font-family: \"";
76 private const string detailHtmlFormat2 = "\", sans-serif; font-size: ";
77 private const string detailHtmlFormat3 = "pt; margin: 0; word-wrap: break-word; color:rgb(";
78 private const string detailHtmlFormat4 = ");} a:link, a:visited, a:active, a:hover {color:rgb(";
79 private const string detailHtmlFormat5 = "); } --></style></head><body style=\"margin:0px; background-color:rgb(";
80 private const string detailHtmlFormatMono6 = ");\"><pre>";
81 private const string detailHtmlFormatMono7 = "</pre></body></html>";
82 private const string detailHtmlFormat1 = "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=8\"><style type=\"text/css\"><!-- p {font-family: \"";
83 private const string detailHtmlFormat6 = ");\"><p><span style=\"vertical-align:text-bottom\">";
84 private const string detailHtmlFormat7 = "</span></p></body></html>";
85 private string detailHtmlFormatHeader;
86 private string detailHtmlFormatFooter;
87 private bool _myStatusError = false;
88 private bool _myStatusOnline = false;
89 private bool soundfileListup = false;
90 private SpaceKeyCanceler _spaceKeyCanceler;
91 private FormWindowState _formWindowState = FormWindowState.Normal; // フォームの状態保存用 通知領域からアイコンをクリックして復帰した際に使用する
94 //private SettingToConfig _cfg; //旧
95 private SettingLocal _cfgLocal;
96 private SettingCommon _cfgCommon;
97 private bool _modifySettingLocal = false;
98 private bool _modifySettingCommon = false;
99 private bool _modifySettingAtId = false;
102 private Twitter tw = new Twitter();
105 private GrowlHelper gh = new GrowlHelper(Application.ProductName);
108 private AppendSettingDialog SettingDialog = AppendSettingDialog.Instance; //設定画面インスタンス
109 private SearchWord SearchDialog = new SearchWord(); //検索画面インスタンス
110 private FilterDialog fltDialog = new FilterDialog(); //フィルター編集画面
111 private OpenURL UrlDialog = new OpenURL();
112 public AtIdSupplement AtIdSupl; //@id補助
113 public AtIdSupplement HashSupl; //Hashtag補助
114 public HashtagManage HashMgr;
115 private EventViewerDialog evtDialog;
118 private Font _fntUnread; //未読用フォント
119 private Color _clUnread; //未読用文字色
120 private Font _fntReaded; //既読用フォント
121 private Color _clReaded; //既読用文字色
122 private Color _clFav; //Fav用文字色
123 private Color _clOWL; //片思い用文字色
124 private Color _clRetweet; //Retweet用文字色
125 private Font _fntDetail; //発言詳細部用フォント
126 private Color _clDetail; //発言詳細部用色
127 private Color _clDetailLink; //発言詳細部用リンク文字色
128 private Color _clDetailBackcolor; //発言詳細部用背景色
129 private Color _clSelf; //自分の発言用背景色
130 private Color _clAtSelf; //自分宛返信用背景色
131 private Color _clTarget; //選択発言者の他の発言用背景色
132 private Color _clAtTarget; //選択発言中の返信先用背景色
133 private Color _clAtFromTarget; //選択発言者への返信発言用背景色
134 private Color _clAtTo; //選択発言の唯一@先
135 private Color _clListBackcolor; //リスト部通常発言背景色
136 private Color _clInputBackcolor; //入力欄背景色
137 private Color _clInputFont; //入力欄文字色
138 private Font _fntInputFont; //入力欄フォント
139 private ImageCache IconCache; //アイコン画像リスト
140 private Icon NIconAt; //At.ico タスクトレイアイコン:通常時
141 private Icon NIconAtRed; //AtRed.ico タスクトレイアイコン:通信エラー時
142 private Icon NIconAtSmoke; //AtSmoke.ico タスクトレイアイコン:オフライン時
143 private Icon[] NIconRefresh = new Icon[4]; //Refresh.ico タスクトレイアイコン:更新中(アニメーション用に4種類を保持するリスト)
144 private Icon TabIcon; //Tab.ico 未読のあるタブ用アイコン
145 private Icon MainIcon; //Main.ico 画面左上のアイコン
146 private Icon ReplyIcon; //5g
147 private Icon ReplyIconBlink; //6g
149 private PostClass _anchorPost;
150 private bool _anchorFlag; //true:関連発言移動中(関連移動以外のオペレーションをするとfalseへ。trueだとリスト背景色をアンカー発言選択中として描画)
152 private List<PostingStatus> _history = new List<PostingStatus>(); //発言履歴
153 private int _hisIdx; //発言履歴カレントインデックス
155 //発言投稿時のAPI引数(発言編集時に設定。手書きreplyでは設定されない)
156 private long _reply_to_id; // リプライ先のステータスID 0の場合はリプライではない 注:複数あてのものはリプライではない
157 private string _reply_to_name; // リプライ先ステータスの書き込み者の名前
160 private List<DateTime> _postTimestamps = new List<DateTime>();
161 private List<DateTime> _favTimestamps = new List<DateTime>();
162 private Dictionary<DateTime, int> _tlTimestamps = new Dictionary<DateTime, int>();
163 private int _tlCount;
166 private SolidBrush _brsHighLight = new SolidBrush(Color.FromKnownColor(KnownColor.Highlight));
167 private SolidBrush _brsHighLightText = new SolidBrush(Color.FromKnownColor(KnownColor.HighlightText));
168 private SolidBrush _brsForeColorUnread;
169 private SolidBrush _brsForeColorReaded;
170 private SolidBrush _brsForeColorFav;
171 private SolidBrush _brsForeColorOWL;
172 private SolidBrush _brsForeColorRetweet;
173 private SolidBrush _brsBackColorMine;
174 private SolidBrush _brsBackColorAt;
175 private SolidBrush _brsBackColorYou;
176 private SolidBrush _brsBackColorAtYou;
177 private SolidBrush _brsBackColorAtFromTarget;
178 private SolidBrush _brsBackColorAtTo;
179 private SolidBrush _brsBackColorNone;
180 private SolidBrush _brsDeactiveSelection = new SolidBrush(Color.FromKnownColor(KnownColor.ButtonFace)); //Listにフォーカスないときの選択行の背景色
181 private StringFormat sfTab = new StringFormat();
183 //////////////////////////////////////////////////////////////////////////////////////////////////////////
184 private ToolStripAPIGauge _apiGauge;
185 private TabInformations _statuses;
187 // ListViewItem のキャッシュ関連
188 private int _itemCacheIndex;
189 private ListViewItem[] _itemCache;
190 private PostClass[] _postCache;
191 private ReaderWriterLockSlim itemCacheLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
193 private TabPage _curTab;
194 private int _curItemIndex;
195 private DetailsListView _curList;
196 private PostClass _curPost;
197 private bool _isColumnChanged = false;
198 private bool _waitTimeline = false;
199 private bool _waitReply = false;
200 private bool _waitDm = false;
201 private bool _waitFav = false;
202 private bool _waitPubSearch = false;
203 private bool _waitUserTimeline = false;
204 private bool _waitLists = false;
205 private BackgroundWorker[] _bw = new BackgroundWorker[20];
206 private BackgroundWorker _bwFollower;
207 private InternetSecurityManager SecurityManager;
209 private int UnreadCounter = -1;
210 private int UnreadAtCounter = -1;
212 private string[] ColumnOrgText = new string[9];
213 private string[] ColumnText = new string[9];
215 private bool _DoFavRetweetFlags = false;
216 private bool osResumed = false;
217 private Dictionary<string, IMultimediaShareService> pictureService;
219 //////////////////////////////////////////////////////////////////////////////////////////////////////////
220 private string _postBrowserStatusText = "";
222 private bool _colorize = false;
224 private System.Timers.Timer TimerTimeline = new System.Timers.Timer();
226 private ImageListViewItem displayItem;
229 private struct urlUndo
231 public string Before;
235 private List<urlUndo> urlUndoBuffer = null;
237 private struct ReplyChain
239 public long OriginalId;
240 public long InReplyToId;
241 public TabPage OriginalTab;
243 public ReplyChain(long originalId, long inReplyToId, TabPage originalTab)
245 this.OriginalId = originalId;
246 this.InReplyToId = inReplyToId;
247 this.OriginalTab = originalTab;
251 private Stack<ReplyChain> replyChains; //[, ]でのリプライ移動の履歴
252 private Stack<Tuple<TabPage, PostClass>> selectPostChains = new Stack<Tuple<TabPage, PostClass>>(); //ポスト選択履歴
254 //Backgroundworkerの処理結果通知用引数構造体
255 private class GetWorkerResult
257 public string retMsg = ""; //処理結果詳細メッセージ。エラー時に値がセットされる
258 public int page; //取得対象ページ番号
259 public int endPage = 0; //取得終了ページ番号(継続可能ならインクリメントされて返る。pageと比較して継続判定)
260 public MyCommon.WORKERTYPE type; //処理種別
261 public Dictionary<string, Image> imgs = null; //新規取得したアイコンイメージ
262 public string tName = ""; //Fav追加・削除時のタブ名
263 public List<long> ids = null; //Fav追加・削除時のID
264 public List<long> sIds = null; //Fav追加・削除成功分のID
265 public bool newDM = false;
267 public PostingStatus status;
270 //Backgroundworkerへ処理内容を通知するための引数用構造体
271 private class GetWorkerArg
273 public int page; //処理対象ページ番号
274 public int endPage; //処理終了ページ番号(起動時の読み込みページ数。通常時はpageと同じ値をセット)
275 public MyCommon.WORKERTYPE type; //処理種別
276 public string url = ""; //URLをブラウザで開くときのアドレス
277 public PostingStatus status = new PostingStatus(); //発言POST時の発言内容
278 public List<long> ids; //Fav追加・削除時のItemIndex
279 public List<long> sIds; //Fav追加・削除成功分のItemIndex
280 public string tName = ""; //Fav追加・削除時のタブ名
284 private enum SEARCHTYPE
291 private class PostingStatus
293 public string status = "";
294 public long inReplyToId = 0;
295 public string inReplyToName = "";
296 public string imageService = ""; //画像投稿サービス名
297 public string imagePath = "";
298 public PostingStatus()
301 public PostingStatus(string status, long replyToId, string replyToName)
303 this.status = status;
304 this.inReplyToId = replyToId;
305 this.inReplyToName = replyToName;
309 private class SpaceKeyCanceler : NativeWindow, IDisposable
311 int WM_KEYDOWN = 0x100;
314 public SpaceKeyCanceler(Control control)
316 this.AssignHandle(control.Handle);
319 protected override void WndProc(ref Message m)
321 if ((m.Msg == WM_KEYDOWN) && ((int)m.WParam == VK_SPACE))
323 if (SpaceCancel != null)
324 SpaceCancel(this, EventArgs.Empty);
331 public event EventHandler SpaceCancel;
333 public void Dispose()
335 this.ReleaseHandle();
339 private void TweenMain_Activated(object sender, EventArgs e)
341 //画面がアクティブになったら、発言欄の背景色戻す
342 if (StatusText.Focused)
344 this.StatusText_Enter(this.StatusText, System.EventArgs.Empty);
348 private void TweenMain_Disposed(object sender, EventArgs e)
351 SettingDialog.Dispose();
352 SearchDialog.Dispose();
355 _spaceKeyCanceler.Dispose();
356 if (NIconAt != null) NIconAt.Dispose();
357 if (NIconAtRed != null) NIconAtRed.Dispose();
358 if (NIconAtSmoke != null) NIconAtSmoke.Dispose();
359 if (NIconRefresh[0] != null) NIconRefresh[0].Dispose();
360 if (NIconRefresh[1] != null) NIconRefresh[1].Dispose();
361 if (NIconRefresh[2] != null) NIconRefresh[2].Dispose();
362 if (NIconRefresh[3] != null) NIconRefresh[3].Dispose();
363 if (TabIcon != null) TabIcon.Dispose();
364 if (MainIcon != null) MainIcon.Dispose();
365 if (ReplyIcon != null) ReplyIcon.Dispose();
366 if (ReplyIconBlink != null) ReplyIconBlink.Dispose();
367 _brsHighLight.Dispose();
368 _brsHighLightText.Dispose();
369 if (_brsForeColorUnread != null) _brsForeColorUnread.Dispose();
370 if (_brsForeColorReaded != null) _brsForeColorReaded.Dispose();
371 if (_brsForeColorFav != null) _brsForeColorFav.Dispose();
372 if (_brsForeColorOWL != null) _brsForeColorOWL.Dispose();
373 if (_brsForeColorRetweet != null) _brsForeColorRetweet.Dispose();
374 if (_brsBackColorMine != null) _brsBackColorMine.Dispose();
375 if (_brsBackColorAt != null) _brsBackColorAt.Dispose();
376 if (_brsBackColorYou != null) _brsBackColorYou.Dispose();
377 if (_brsBackColorAtYou != null) _brsBackColorAtYou.Dispose();
378 if (_brsBackColorAtFromTarget != null) _brsBackColorAtFromTarget.Dispose();
379 if (_brsBackColorAtTo != null) _brsBackColorAtTo.Dispose();
380 if (_brsBackColorNone != null) _brsBackColorNone.Dispose();
381 if (_brsDeactiveSelection != null) _brsDeactiveSelection.Dispose();
384 foreach (BackgroundWorker bw in _bw)
389 if (_bwFollower != null)
391 _bwFollower.Dispose();
393 this._apiGauge.Dispose();
394 if (IconCache != null)
396 this.IconCache.CancelAsync();
397 this.IconCache.Dispose();
399 // 終了時にRemoveHandlerしておかないとメモリリークする
400 // http://msdn.microsoft.com/ja-jp/library/microsoft.win32.systemevents.powermodechanged.aspx
401 Microsoft.Win32.SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
404 private void LoadIcon(ref Icon IconInstance, string FileName)
406 string dir = Application.StartupPath;
407 if (File.Exists(Path.Combine(dir, FileName)))
411 IconInstance = new Icon(Path.Combine(dir, FileName));
419 private void LoadIcons()
423 string dir = Application.StartupPath;
425 NIconAt = Properties.Resources.At;
426 NIconAtRed = Properties.Resources.AtRed;
427 NIconAtSmoke = Properties.Resources.AtSmoke;
428 NIconRefresh[0] = Properties.Resources.Refresh;
429 NIconRefresh[1] = Properties.Resources.Refresh2;
430 NIconRefresh[2] = Properties.Resources.Refresh3;
431 NIconRefresh[3] = Properties.Resources.Refresh4;
432 TabIcon = Properties.Resources.TabIcon;
433 MainIcon = Properties.Resources.MIcon;
434 ReplyIcon = Properties.Resources.Reply;
435 ReplyIconBlink = Properties.Resources.ReplyBlink;
437 if (!Directory.Exists(Path.Combine(dir, "Icons")))
440 LoadIcon(ref NIconAt, "Icons\\At.ico");
443 LoadIcon(ref NIconAtRed, "Icons\\AtRed.ico");
446 LoadIcon(ref NIconAtSmoke, "Icons\\AtSmoke.ico");
449 //アニメーション対応により4種類読み込み
450 LoadIcon(ref NIconRefresh[0], "Icons\\Refresh.ico");
451 LoadIcon(ref NIconRefresh[1], "Icons\\Refresh2.ico");
452 LoadIcon(ref NIconRefresh[2], "Icons\\Refresh3.ico");
453 LoadIcon(ref NIconRefresh[3], "Icons\\Refresh4.ico");
456 LoadIcon(ref TabIcon, "Icons\\Tab.ico");
459 LoadIcon(ref MainIcon, "Icons\\MIcon.ico");
462 LoadIcon(ref ReplyIcon, "Icons\\Reply.ico");
465 LoadIcon(ref ReplyIconBlink, "Icons\\ReplyBlink.ico");
468 private void InitColumnText()
471 ColumnText[1] = Properties.Resources.AddNewTabText2;
472 ColumnText[2] = Properties.Resources.AddNewTabText3;
473 ColumnText[3] = Properties.Resources.AddNewTabText4_2;
474 ColumnText[4] = Properties.Resources.AddNewTabText5;
477 ColumnText[7] = "Source";
479 ColumnOrgText[0] = "";
480 ColumnOrgText[1] = Properties.Resources.AddNewTabText2;
481 ColumnOrgText[2] = Properties.Resources.AddNewTabText3;
482 ColumnOrgText[3] = Properties.Resources.AddNewTabText4_2;
483 ColumnOrgText[4] = Properties.Resources.AddNewTabText5;
484 ColumnOrgText[5] = "";
485 ColumnOrgText[6] = "";
486 ColumnOrgText[7] = "Source";
489 switch (_statuses.SortMode)
491 case IdComparerClass.ComparerMode.Nickname: //ニックネーム
494 case IdComparerClass.ComparerMode.Data: //本文
497 case IdComparerClass.ComparerMode.Id: //時刻=発言Id
500 case IdComparerClass.ComparerMode.Name: //名前
503 case IdComparerClass.ComparerMode.Source: //Source
510 if (_statuses.SortOrder == SortOrder.Descending)
512 // U+25BE BLACK DOWN-POINTING SMALL TRIANGLE
513 ColumnText[2] = ColumnOrgText[2] + "▾";
517 // U+25B4 BLACK UP-POINTING SMALL TRIANGLE
518 ColumnText[2] = ColumnOrgText[2] + "▴";
523 if (_statuses.SortOrder == SortOrder.Descending)
525 // U+25BE BLACK DOWN-POINTING SMALL TRIANGLE
526 ColumnText[c] = ColumnOrgText[c] + "▾";
530 // U+25B4 BLACK UP-POINTING SMALL TRIANGLE
531 ColumnText[c] = ColumnOrgText[c] + "▴";
536 private void InitializeTraceFrag()
539 TraceOutToolStripMenuItem.Checked = true;
540 MyCommon.TraceFlag = true;
542 if (!MyCommon.fileVersion.EndsWith("0"))
544 TraceOutToolStripMenuItem.Checked = true;
545 MyCommon.TraceFlag = true;
549 private void Form1_Load(object sender, EventArgs e)
551 _ignoreConfigSave = true;
552 this.Visible = false;
554 //Win32Api.SetProxy(HttpConnection.ProxyType.Specified, "127.0.0.1", 8080, "user", "pass")
556 SecurityManager = new InternetSecurityManager(PostBrowser);
558 MyCommon.TwitterApiInfo.AccessLimitUpdated += TwitterApiStatus_AccessLimitUpdated;
559 MyCommon.TwitterApiInfo11.AccessLimitUpdated += TwitterApiStatus_AccessLimitUpdated;
560 Microsoft.Win32.SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
562 string[] cmdArgs = Environment.GetCommandLineArgs();
563 if (cmdArgs.Length != 0 && cmdArgs.Contains("/d")) MyCommon.TraceFlag = true;
565 this._spaceKeyCanceler = new SpaceKeyCanceler(this.PostButton);
566 this._spaceKeyCanceler.SpaceCancel += spaceKeyCanceler_SpaceCancel;
568 Regex.CacheSize = 100;
570 MyCommon.fileVersion = ((AssemblyFileVersionAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyFileVersionAttribute), false)[0]).Version;
571 InitializeTraceFrag();
572 LoadIcons(); // アイコン読み込み
574 ThumbnailGenerator.InitializeGenerator();
577 _statuses = TabInformations.GetInstance();
580 this.Icon = MainIcon; //メインフォーム(TweenMain)
581 NotifyIcon1.Icon = NIconAt; //タスクトレイ
582 TabImage.Images.Add(TabIcon); //タブ見出し
584 SettingDialog.Owner = this;;
585 SearchDialog.Owner = this;
586 fltDialog.Owner = this;
587 UrlDialog.Owner = this;
589 _history.Add(new PostingStatus());
594 //<<<<<<<<<設定関連>>>>>>>>>
602 NewPostPopMenuItem.Checked = _cfgCommon.NewAllPop;
603 this.NotifyFileMenuItem.Checked = NewPostPopMenuItem.Checked;
606 _fntUnread = _cfgLocal.FontUnread;
607 _clUnread = _cfgLocal.ColorUnread;
608 _fntReaded = _cfgLocal.FontRead;
609 _clReaded = _cfgLocal.ColorRead;
610 _clFav = _cfgLocal.ColorFav;
611 _clOWL = _cfgLocal.ColorOWL;
612 _clRetweet = _cfgLocal.ColorRetweet;
613 _fntDetail = _cfgLocal.FontDetail;
614 _clDetail = _cfgLocal.ColorDetail;
615 _clDetailLink = _cfgLocal.ColorDetailLink;
616 _clDetailBackcolor = _cfgLocal.ColorDetailBackcolor;
617 _clSelf = _cfgLocal.ColorSelf;
618 _clAtSelf = _cfgLocal.ColorAtSelf;
619 _clTarget = _cfgLocal.ColorTarget;
620 _clAtTarget = _cfgLocal.ColorAtTarget;
621 _clAtFromTarget = _cfgLocal.ColorAtFromTarget;
622 _clAtTo = _cfgLocal.ColorAtTo;
623 _clListBackcolor = _cfgLocal.ColorListBackcolor;
624 _clInputBackcolor = _cfgLocal.ColorInputBackcolor;
625 _clInputFont = _cfgLocal.ColorInputFont;
626 _fntInputFont = _cfgLocal.FontInputFont;
628 _brsForeColorUnread = new SolidBrush(_clUnread);
629 _brsForeColorReaded = new SolidBrush(_clReaded);
630 _brsForeColorFav = new SolidBrush(_clFav);
631 _brsForeColorOWL = new SolidBrush(_clOWL);
632 _brsForeColorRetweet = new SolidBrush(_clRetweet);
633 _brsBackColorMine = new SolidBrush(_clSelf);
634 _brsBackColorAt = new SolidBrush(_clAtSelf);
635 _brsBackColorYou = new SolidBrush(_clTarget);
636 _brsBackColorAtYou = new SolidBrush(_clAtTarget);
637 _brsBackColorAtFromTarget = new SolidBrush(_clAtFromTarget);
638 _brsBackColorAtTo = new SolidBrush(_clAtTo);
639 //_brsBackColorNone = new SolidBrush(Color.FromKnownColor(KnownColor.Window));
640 _brsBackColorNone = new SolidBrush(_clListBackcolor);
642 // StringFormatオブジェクトへの事前設定
643 //sf.Alignment = StringAlignment.Near; // Textを近くへ配置(左から右の場合は左寄せ)
644 //sf.LineAlignment = StringAlignment.Near; // Textを近くへ配置(上寄せ)
645 //sf.FormatFlags = StringFormatFlags.LineLimit; //
646 sfTab.Alignment = StringAlignment.Center;
647 sfTab.LineAlignment = StringAlignment.Center;
650 HttpTwitter.TwitterUrl = _cfgCommon.TwitterUrl;
651 HttpTwitter.TwitterSearchUrl = _cfgCommon.TwitterSearchUrl;
652 SettingDialog.TwitterApiUrl = _cfgCommon.TwitterUrl;
653 SettingDialog.TwitterSearchApiUrl = _cfgCommon.TwitterSearchUrl;
656 if (string.IsNullOrEmpty(_cfgCommon.Token)) _cfgCommon.UserName = "";
657 tw.Initialize(_cfgCommon.Token, _cfgCommon.TokenSecret, _cfgCommon.UserName, _cfgCommon.UserId);
659 SettingDialog.UserAccounts = _cfgCommon.UserAccounts;
661 SettingDialog.TimelinePeriodInt = _cfgCommon.TimelinePeriod;
662 SettingDialog.ReplyPeriodInt = _cfgCommon.ReplyPeriod;
663 SettingDialog.DMPeriodInt = _cfgCommon.DMPeriod;
664 SettingDialog.PubSearchPeriodInt = _cfgCommon.PubSearchPeriod;
665 SettingDialog.UserTimelinePeriodInt = _cfgCommon.UserTimelinePeriod;
666 SettingDialog.ListsPeriodInt = _cfgCommon.ListsPeriod;
668 if (!cmdArgs.Contains("nolimit"))
670 if (SettingDialog.TimelinePeriodInt < 15 && SettingDialog.TimelinePeriodInt > 0) SettingDialog.TimelinePeriodInt = 15;
671 if (SettingDialog.ReplyPeriodInt < 15 && SettingDialog.ReplyPeriodInt > 0) SettingDialog.ReplyPeriodInt = 15;
672 if (SettingDialog.DMPeriodInt < 15 && SettingDialog.DMPeriodInt > 0) SettingDialog.DMPeriodInt = 15;
673 if (SettingDialog.PubSearchPeriodInt < 30 && SettingDialog.PubSearchPeriodInt > 0) SettingDialog.PubSearchPeriodInt = 30;
674 if (SettingDialog.UserTimelinePeriodInt < 15 && SettingDialog.UserTimelinePeriodInt > 0) SettingDialog.UserTimelinePeriodInt = 15;
675 if (SettingDialog.ListsPeriodInt < 15 && SettingDialog.ListsPeriodInt > 0) SettingDialog.ListsPeriodInt = 15;
678 //起動時読み込み分を既読にするか。trueなら既読として処理
679 SettingDialog.Readed = _cfgCommon.Read;
680 //新着取得時のリストスクロールをするか。trueならスクロールしない
681 ListLockMenuItem.Checked = _cfgCommon.ListLock;
682 this.LockListFileMenuItem.Checked = _cfgCommon.ListLock;
683 SettingDialog.IconSz = _cfgCommon.IconSize;
685 SettingDialog.Status = _cfgLocal.StatusText;
687 SettingDialog.UnreadManage = _cfgCommon.UnreadManage;
689 SettingDialog.PlaySound = _cfgCommon.PlaySound;
690 PlaySoundMenuItem.Checked = SettingDialog.PlaySound;
691 this.PlaySoundFileMenuItem.Checked = SettingDialog.PlaySound;
692 //片思い表示。trueなら片思い表示する
693 SettingDialog.OneWayLove = _cfgCommon.OneWayLove;
695 SettingDialog.FontUnread = _fntUnread;
696 SettingDialog.ColorUnread = _clUnread;
697 SettingDialog.FontReaded = _fntReaded;
698 SettingDialog.ColorReaded = _clReaded;
699 SettingDialog.ColorFav = _clFav;
700 SettingDialog.ColorOWL = _clOWL;
701 SettingDialog.ColorRetweet = _clRetweet;
702 SettingDialog.FontDetail = _fntDetail;
703 SettingDialog.ColorDetail = _clDetail;
704 SettingDialog.ColorDetailLink = _clDetailLink;
705 SettingDialog.ColorDetailBackcolor = _clDetailBackcolor;
706 SettingDialog.ColorSelf = _clSelf;
707 SettingDialog.ColorAtSelf = _clAtSelf;
708 SettingDialog.ColorTarget = _clTarget;
709 SettingDialog.ColorAtTarget = _clAtTarget;
710 SettingDialog.ColorAtFromTarget = _clAtFromTarget;
711 SettingDialog.ColorAtTo = _clAtTo;
712 SettingDialog.ColorListBackcolor = _clListBackcolor;
713 SettingDialog.ColorInputBackcolor = _clInputBackcolor;
714 SettingDialog.ColorInputFont = _clInputFont;
715 SettingDialog.FontInputFont = _fntInputFont;
717 SettingDialog.NameBalloon = _cfgCommon.NameBalloon;
718 SettingDialog.PostCtrlEnter = _cfgCommon.PostCtrlEnter;
719 SettingDialog.PostShiftEnter = _cfgCommon.PostShiftEnter;
721 SettingDialog.CountApi = _cfgCommon.CountApi;
722 SettingDialog.CountApiReply = _cfgCommon.CountApiReply;
723 if (SettingDialog.CountApi < 20 || SettingDialog.CountApi > 200) SettingDialog.CountApi = 60;
724 if (SettingDialog.CountApiReply < 20 || SettingDialog.CountApiReply > 200) SettingDialog.CountApiReply = 40;
726 SettingDialog.BrowserPath = _cfgLocal.BrowserPath;
727 SettingDialog.PostAndGet = _cfgCommon.PostAndGet;
728 SettingDialog.UseRecommendStatus = _cfgLocal.UseRecommendStatus;
729 SettingDialog.DispUsername = _cfgCommon.DispUsername;
730 SettingDialog.CloseToExit = _cfgCommon.CloseToExit;
731 SettingDialog.MinimizeToTray = _cfgCommon.MinimizeToTray;
732 SettingDialog.DispLatestPost = _cfgCommon.DispLatestPost;
733 SettingDialog.SortOrderLock = _cfgCommon.SortOrderLock;
734 SettingDialog.ViewTabBottom = _cfgCommon.ViewTabBottom;
735 SettingDialog.TinyUrlResolve = _cfgCommon.TinyUrlResolve;
736 SettingDialog.ShortUrlForceResolve = _cfgCommon.ShortUrlForceResolve;
738 SettingDialog.SelectedProxyType = _cfgLocal.ProxyType;
739 SettingDialog.ProxyAddress = _cfgLocal.ProxyAddress;
740 SettingDialog.ProxyPort = _cfgLocal.ProxyPort;
741 SettingDialog.ProxyUser = _cfgLocal.ProxyUser;
742 SettingDialog.ProxyPassword = _cfgLocal.ProxyPassword;
744 SettingDialog.PeriodAdjust = _cfgCommon.PeriodAdjust;
745 SettingDialog.StartupVersion = _cfgCommon.StartupVersion;
746 SettingDialog.StartupFollowers = _cfgCommon.StartupFollowers;
747 SettingDialog.RestrictFavCheck = _cfgCommon.RestrictFavCheck;
748 SettingDialog.AlwaysTop = _cfgCommon.AlwaysTop;
749 SettingDialog.UrlConvertAuto = false;
750 //SettingDialog.UrlConvertAuto = _cfgCommon.UrlConvertAuto;
752 SettingDialog.OutputzEnabled = _cfgCommon.Outputz;
753 SettingDialog.OutputzKey = _cfgCommon.OutputzKey;
754 SettingDialog.OutputzUrlmode = _cfgCommon.OutputzUrlMode;
756 SettingDialog.UseUnreadStyle = _cfgCommon.UseUnreadStyle;
757 SettingDialog.DefaultTimeOut = _cfgCommon.DefaultTimeOut;
758 SettingDialog.RetweetNoConfirm = _cfgCommon.RetweetNoConfirm;
759 SettingDialog.PlaySound = _cfgCommon.PlaySound;
760 SettingDialog.DateTimeFormat = _cfgCommon.DateTimeFormat;
761 SettingDialog.LimitBalloon = _cfgCommon.LimitBalloon;
762 SettingDialog.EventNotifyEnabled = _cfgCommon.EventNotifyEnabled;
763 SettingDialog.EventNotifyFlag = _cfgCommon.EventNotifyFlag;
764 SettingDialog.IsMyEventNotifyFlag = _cfgCommon.IsMyEventNotifyFlag;
765 SettingDialog.ForceEventNotify = _cfgCommon.ForceEventNotify;
766 SettingDialog.FavEventUnread = _cfgCommon.FavEventUnread;
767 SettingDialog.TranslateLanguage = _cfgCommon.TranslateLanguage;
768 SettingDialog.EventSoundFile = _cfgCommon.EventSoundFile;
770 //廃止サービスが選択されていた場合bit.lyへ読み替え
771 if (_cfgCommon.AutoShortUrlFirst < 0)
772 _cfgCommon.AutoShortUrlFirst = MyCommon.UrlConverter.Uxnu;
774 SettingDialog.AutoShortUrlFirst = _cfgCommon.AutoShortUrlFirst;
775 SettingDialog.TabIconDisp = _cfgCommon.TabIconDisp;
776 SettingDialog.ReplyIconState = _cfgCommon.ReplyIconState;
777 SettingDialog.ReadOwnPost = _cfgCommon.ReadOwnPost;
778 SettingDialog.GetFav = _cfgCommon.GetFav;
779 SettingDialog.ReadOldPosts = _cfgCommon.ReadOldPosts;
780 SettingDialog.UseSsl = _cfgCommon.UseSsl;
781 SettingDialog.BitlyUser = _cfgCommon.BilyUser;
782 SettingDialog.BitlyPwd = _cfgCommon.BitlyPwd;
783 SettingDialog.ShowGrid = _cfgCommon.ShowGrid;
784 SettingDialog.Language = _cfgCommon.Language;
785 SettingDialog.UseAtIdSupplement = _cfgCommon.UseAtIdSupplement;
786 SettingDialog.UseHashSupplement = _cfgCommon.UseHashSupplement;
787 SettingDialog.PreviewEnable = _cfgCommon.PreviewEnable;
788 AtIdSupl = new AtIdSupplement(SettingAtIdList.Load().AtIdList, "@");
790 SettingDialog.IsMonospace = _cfgCommon.IsMonospace;
791 if (SettingDialog.IsMonospace)
793 detailHtmlFormatHeader = detailHtmlFormatMono1;
794 detailHtmlFormatFooter = detailHtmlFormatMono7;
798 detailHtmlFormatHeader = detailHtmlFormat1;
799 detailHtmlFormatFooter = detailHtmlFormat7;
801 detailHtmlFormatHeader += _fntDetail.Name + detailHtmlFormat2 + _fntDetail.Size.ToString() + detailHtmlFormat3 + _clDetail.R.ToString() + "," + _clDetail.G.ToString() + "," + _clDetail.B.ToString() + detailHtmlFormat4 + _clDetailLink.R.ToString() + "," + _clDetailLink.G.ToString() + "," + _clDetailLink.B.ToString() + detailHtmlFormat5 + _clDetailBackcolor.R.ToString() + "," + _clDetailBackcolor.G.ToString() + "," + _clDetailBackcolor.B.ToString();
802 if (SettingDialog.IsMonospace)
804 detailHtmlFormatHeader += detailHtmlFormatMono6;
808 detailHtmlFormatHeader += detailHtmlFormat6;
810 this.IdeographicSpaceToSpaceToolStripMenuItem.Checked = _cfgCommon.WideSpaceConvert;
811 this.ToolStripFocusLockMenuItem.Checked = _cfgCommon.FocusLockToStatusText;
813 //Regex statregex = new Regex("^0*");
814 SettingDialog.RecommendStatusText = " [TWNv" + Regex.Replace(MyCommon.fileVersion.Replace(".", ""), "^0*", "") + "]";
819 if (DateTime.Now.ToString(SettingDialog.DateTimeFormat).Length == 0)
821 // このブロックは絶対に実行されないはず
822 // 変換が成功した場合にLengthが0にならない
823 SettingDialog.DateTimeFormat = "yyyy/MM/dd H:mm:ss";
826 catch (FormatException)
828 // FormatExceptionが発生したら初期値を設定 (=yyyy/MM/dd H:mm:ssとみなされる)
829 SettingDialog.DateTimeFormat = "yyyy/MM/dd H:mm:ss";
832 SettingDialog.Nicoms = _cfgCommon.Nicoms;
833 SettingDialog.HotkeyEnabled = _cfgCommon.HotkeyEnabled;
834 SettingDialog.HotkeyMod = _cfgCommon.HotkeyModifier;
835 SettingDialog.HotkeyKey = _cfgCommon.HotkeyKey;
836 SettingDialog.HotkeyValue = _cfgCommon.HotkeyValue;
838 SettingDialog.BlinkNewMentions = _cfgCommon.BlinkNewMentions;
840 SettingDialog.UseAdditionalCount = _cfgCommon.UseAdditionalCount;
841 SettingDialog.MoreCountApi = _cfgCommon.MoreCountApi;
842 SettingDialog.FirstCountApi = _cfgCommon.FirstCountApi;
843 SettingDialog.SearchCountApi = _cfgCommon.SearchCountApi;
844 SettingDialog.FavoritesCountApi = _cfgCommon.FavoritesCountApi;
845 SettingDialog.UserTimelineCountApi = _cfgCommon.UserTimelineCountApi;
846 SettingDialog.ListCountApi = _cfgCommon.ListCountApi;
848 SettingDialog.UserstreamStartup = _cfgCommon.UserstreamStartup;
849 SettingDialog.UserstreamPeriodInt = _cfgCommon.UserstreamPeriod;
850 SettingDialog.OpenUserTimeline = _cfgCommon.OpenUserTimeline;
851 SettingDialog.ListDoubleClickAction = _cfgCommon.ListDoubleClickAction;
852 SettingDialog.UserAppointUrl = _cfgCommon.UserAppointUrl;
853 SettingDialog.HideDuplicatedRetweets = _cfgCommon.HideDuplicatedRetweets;
855 SettingDialog.IsPreviewFoursquare = _cfgCommon.IsPreviewFoursquare;
856 SettingDialog.MapThumbnailProvider = _cfgCommon.MapThumbnailProvider;
857 SettingDialog.MapThumbnailHeight = _cfgCommon.MapThumbnailHeight;
858 SettingDialog.MapThumbnailWidth = _cfgCommon.MapThumbnailWidth;
859 SettingDialog.MapThumbnailZoom = _cfgCommon.MapThumbnailZoom;
860 SettingDialog.IsListStatusesIncludeRts = _cfgCommon.IsListsIncludeRts;
861 SettingDialog.TabMouseLock = _cfgCommon.TabMouseLock;
862 SettingDialog.IsRemoveSameEvent = _cfgCommon.IsRemoveSameEvent;
863 SettingDialog.IsNotifyUseGrowl = _cfgCommon.IsUseNotifyGrowl;
866 HashSupl = new AtIdSupplement(_cfgCommon.HashTags, "#");
867 HashMgr = new HashtagManage(HashSupl,
868 _cfgCommon.HashTags.ToArray(),
869 _cfgCommon.HashSelected,
870 _cfgCommon.HashIsPermanent,
871 _cfgCommon.HashIsHead,
872 _cfgCommon.HashIsNotAddToAtReply);
873 if (!string.IsNullOrEmpty(HashMgr.UseHash) && HashMgr.IsPermanent) HashStripSplitButton.Text = HashMgr.UseHash;
878 this.IconCache = new ImageCache();
880 bool saveRequired = false;
881 bool firstRun = false;
883 //ユーザー名、パスワードが未設定なら設定画面を表示(初回起動時など)
884 if (string.IsNullOrEmpty(tw.Username))
888 SettingDialog.ShowInTaskbar = true;
890 //設定せずにキャンセルされた場合はプログラム終了
891 if (SettingDialog.ShowDialog(this) == DialogResult.Cancel)
893 Application.Exit(); //強制終了
896 //設定されたが、依然ユーザー名とパスワードが未設定ならプログラム終了
897 if (string.IsNullOrEmpty(tw.Username))
899 Application.Exit(); //強制終了
902 SettingDialog.ShowInTaskbar = false;
905 _fntUnread = SettingDialog.FontUnread;
906 _clUnread = SettingDialog.ColorUnread;
907 _fntReaded = SettingDialog.FontReaded;
908 _clReaded = SettingDialog.ColorReaded;
909 _clFav = SettingDialog.ColorFav;
910 _clOWL = SettingDialog.ColorOWL;
911 _clRetweet = SettingDialog.ColorRetweet;
912 _fntDetail = SettingDialog.FontDetail;
913 _clDetail = SettingDialog.ColorDetail;
914 _clDetailLink = SettingDialog.ColorDetailLink;
915 _clDetailBackcolor = SettingDialog.ColorDetailBackcolor;
916 _clSelf = SettingDialog.ColorSelf;
917 _clAtSelf = SettingDialog.ColorAtSelf;
918 _clTarget = SettingDialog.ColorTarget;
919 _clAtTarget = SettingDialog.ColorAtTarget;
920 _clAtFromTarget = SettingDialog.ColorAtFromTarget;
921 _clAtTo = SettingDialog.ColorAtTo;
922 _clListBackcolor = SettingDialog.ColorListBackcolor;
923 _clInputBackcolor = SettingDialog.ColorInputBackcolor;
924 _clInputFont = SettingDialog.ColorInputFont;
925 _fntInputFont = SettingDialog.FontInputFont;
926 _brsForeColorUnread.Dispose();
927 _brsForeColorReaded.Dispose();
928 _brsForeColorFav.Dispose();
929 _brsForeColorOWL.Dispose();
930 _brsForeColorRetweet.Dispose();
931 _brsForeColorUnread = new SolidBrush(_clUnread);
932 _brsForeColorReaded = new SolidBrush(_clReaded);
933 _brsForeColorFav = new SolidBrush(_clFav);
934 _brsForeColorOWL = new SolidBrush(_clOWL);
935 _brsForeColorRetweet = new SolidBrush(_clRetweet);
936 _brsBackColorMine.Dispose();
937 _brsBackColorAt.Dispose();
938 _brsBackColorYou.Dispose();
939 _brsBackColorAtYou.Dispose();
940 _brsBackColorAtFromTarget.Dispose();
941 _brsBackColorAtTo.Dispose();
942 _brsBackColorNone.Dispose();
943 _brsBackColorMine = new SolidBrush(_clSelf);
944 _brsBackColorAt = new SolidBrush(_clAtSelf);
945 _brsBackColorYou = new SolidBrush(_clTarget);
946 _brsBackColorAtYou = new SolidBrush(_clAtTarget);
947 _brsBackColorAtFromTarget = new SolidBrush(_clAtFromTarget);
948 _brsBackColorAtTo = new SolidBrush(_clAtTo);
949 _brsBackColorNone = new SolidBrush(_clListBackcolor);
951 if (SettingDialog.IsMonospace)
953 detailHtmlFormatHeader = detailHtmlFormatMono1;
954 detailHtmlFormatFooter = detailHtmlFormatMono7;
958 detailHtmlFormatHeader = detailHtmlFormat1;
959 detailHtmlFormatFooter = detailHtmlFormat7;
961 detailHtmlFormatHeader += _fntDetail.Name + detailHtmlFormat2 + _fntDetail.Size.ToString() + detailHtmlFormat3 + _clDetail.R.ToString() + "," + _clDetail.G.ToString() + "," + _clDetail.B.ToString() + detailHtmlFormat4 + _clDetailLink.R.ToString() + "," + _clDetailLink.G.ToString() + "," + _clDetailLink.B.ToString() + detailHtmlFormat5 + _clDetailBackcolor.R.ToString() + "," + _clDetailBackcolor.G.ToString() + "," + _clDetailBackcolor.B.ToString();
962 if (SettingDialog.IsMonospace)
964 detailHtmlFormatHeader += detailHtmlFormatMono6;
968 detailHtmlFormatHeader += detailHtmlFormat6;
970 //他の設定項目は、随時設定画面で保持している値を読み出して使用
973 if (SettingDialog.HotkeyEnabled)
976 HookGlobalHotkey.ModKeys modKey = HookGlobalHotkey.ModKeys.None;
977 if ((SettingDialog.HotkeyMod & Keys.Alt) == Keys.Alt) modKey = modKey | HookGlobalHotkey.ModKeys.Alt;
978 if ((SettingDialog.HotkeyMod & Keys.Control) == Keys.Control) modKey = modKey | HookGlobalHotkey.ModKeys.Ctrl;
979 if ((SettingDialog.HotkeyMod & Keys.Shift) == Keys.Shift) modKey = modKey | HookGlobalHotkey.ModKeys.Shift;
980 if ((SettingDialog.HotkeyMod & Keys.LWin) == Keys.LWin) modKey = modKey | HookGlobalHotkey.ModKeys.Win;
982 _hookGlobalHotkey.RegisterOriginalHotkey(SettingDialog.HotkeyKey, SettingDialog.HotkeyValue, modKey);
986 HttpConnection.InitializeConnection(SettingDialog.DefaultTimeOut,
987 SettingDialog.SelectedProxyType,
988 SettingDialog.ProxyAddress,
989 SettingDialog.ProxyPort,
990 SettingDialog.ProxyUser,
991 SettingDialog.ProxyPassword);
993 tw.RestrictFavCheck = SettingDialog.RestrictFavCheck;
994 tw.ReadOwnPost = SettingDialog.ReadOwnPost;
995 tw.UseSsl = SettingDialog.UseSsl;
996 ShortUrl.IsResolve = SettingDialog.TinyUrlResolve;
997 ShortUrl.IsForceResolve = SettingDialog.ShortUrlForceResolve;
998 ShortUrl.BitlyId = SettingDialog.BitlyUser;
999 ShortUrl.BitlyKey = SettingDialog.BitlyPwd;
1000 HttpTwitter.TwitterUrl = _cfgCommon.TwitterUrl;
1001 HttpTwitter.TwitterSearchUrl = _cfgCommon.TwitterSearchUrl;
1002 tw.TrackWord = _cfgCommon.TrackWord;
1003 TrackToolStripMenuItem.Checked = !String.IsNullOrEmpty(tw.TrackWord);
1004 tw.AllAtReply = _cfgCommon.AllAtReply;
1005 AllrepliesToolStripMenuItem.Checked = tw.AllAtReply;
1007 Outputz.Key = SettingDialog.OutputzKey;
1008 Outputz.Enabled = SettingDialog.OutputzEnabled;
1009 switch (SettingDialog.OutputzUrlmode)
1011 case MyCommon.OutputzUrlmode.twittercom:
1012 Outputz.OutUrl = "http://twitter.com/";
1014 case MyCommon.OutputzUrlmode.twittercomWithUsername:
1015 Outputz.OutUrl = "http://twitter.com/" + tw.Username;
1020 this.CreatePictureServices();
1021 SetImageServiceCombo();
1022 ImageSelectionPanel.Enabled = false;
1024 ImageServiceCombo.SelectedIndex = _cfgCommon.UseImageService;
1027 this.ClientSize = _cfgLocal.FormSize;
1028 _mySize = _cfgLocal.FormSize; //サイズ保持(最小化・最大化されたまま終了した場合の対応用)
1029 _myLoc = _cfgLocal.FormLocation;
1031 if (this.WindowState != FormWindowState.Minimized)
1033 this.DesktopLocation = _cfgLocal.FormLocation;
1034 Rectangle tbarRect = new Rectangle(this.Location, new Size(_mySize.Width, SystemInformation.CaptionHeight));
1035 bool outOfScreen = true;
1036 if (Screen.AllScreens.Length == 1) //ハングするとの報告
1038 foreach (Screen scr in Screen.AllScreens)
1040 if (!Rectangle.Intersect(tbarRect, scr.Bounds).IsEmpty)
1042 outOfScreen = false;
1048 this.DesktopLocation = new Point(0, 0);
1049 _myLoc = this.DesktopLocation;
1053 this.TopMost = SettingDialog.AlwaysTop;
1054 _mySpDis = _cfgLocal.SplitterDistance;
1055 _mySpDis2 = _cfgLocal.StatusTextHeight;
1056 _mySpDis3 = _cfgLocal.PreviewDistance;
1057 if (_mySpDis3 == -1)
1059 _mySpDis3 = _mySize.Width - 150;
1060 if (_mySpDis3 < 1) _mySpDis3 = 50;
1061 _cfgLocal.PreviewDistance = _mySpDis3;
1063 _myAdSpDis = _cfgLocal.AdSplitterDistance;
1064 MultiLineMenuItem.Checked = _cfgLocal.StatusMultiline;
1065 //this.Tween_ClientSizeChanged(this, null);
1066 PlaySoundMenuItem.Checked = SettingDialog.PlaySound;
1067 this.PlaySoundFileMenuItem.Checked = SettingDialog.PlaySound;
1069 StatusText.Font = _fntInputFont;
1070 StatusText.ForeColor = _clInputFont;
1072 //全新着通知のチェック状態により、Reply&DMの新着通知有効無効切り替え(タブ別設定にするため削除予定)
1073 if (SettingDialog.UnreadManage == false)
1075 ReadedStripMenuItem.Enabled = false;
1076 UnreadStripMenuItem.Enabled = false;
1079 if (SettingDialog.IsNotifyUseGrowl) gh.RegisterGrowl();
1082 TimerTimeline.AutoReset = true;
1083 TimerTimeline.SynchronizingObject = this;
1085 TimerTimeline.Interval = 1000;
1086 TimerTimeline.Enabled = true;
1089 TimerRefreshIcon.Interval = 200;
1090 TimerRefreshIcon.Enabled = true;
1093 StatusLabel.Text = "";
1094 StatusLabel.AutoToolTip = false;
1095 StatusLabel.ToolTipText = "";
1097 lblLen.Text = GetRestStatusCount(true, false).ToString();
1099 ////////////////////////////////////////////////////////////////////////////////
1100 _statuses.SortOrder = (SortOrder)_cfgCommon.SortOrder;
1101 IdComparerClass.ComparerMode mode = IdComparerClass.ComparerMode.Id;
1102 switch (_cfgCommon.SortColumn)
1104 case 0: //0:アイコン,5:未読マーク,6:プロテクト・フィルターマーク
1108 mode = IdComparerClass.ComparerMode.Id; //Idソートに読み替え
1111 mode = IdComparerClass.ComparerMode.Nickname;
1114 mode = IdComparerClass.ComparerMode.Data;
1117 mode = IdComparerClass.ComparerMode.Id;
1120 mode = IdComparerClass.ComparerMode.Name;
1123 mode = IdComparerClass.ComparerMode.Source;
1126 _statuses.SortMode = mode;
1127 ////////////////////////////////////////////////////////////////////////////////
1129 switch (SettingDialog.IconSz)
1131 case MyCommon.IconSizes.IconNone:
1134 case MyCommon.IconSizes.Icon16:
1137 case MyCommon.IconSizes.Icon24:
1140 case MyCommon.IconSizes.Icon48:
1143 case MyCommon.IconSizes.Icon48_2:
1155 tw.IconSize = _iconSz;
1157 tw.TinyUrlResolve = SettingDialog.TinyUrlResolve;
1158 ShortUrl.IsForceResolve = SettingDialog.ShortUrlForceResolve;
1160 //発言詳細部アイコンをリストアイコンにサイズ変更
1167 StatusLabel.Text = Properties.Resources.Form1_LoadText1; //画面右下の状態表示を変更
1168 StatusLabelUrl.Text = ""; //画面左下のリンク先URL表示部を初期化
1169 NameLabel.Text = ""; //発言詳細部名前ラベル初期化
1170 DateTimeLabel.Text = ""; //発言詳細部日時ラベル初期化
1171 SourceLinkLabel.Text = ""; //Source部分初期化
1173 //<<<<<<<<タブ関連>>>>>>>
1174 //デフォルトタブの存在チェック、ない場合には追加
1175 if (_statuses.GetTabByType(MyCommon.TabUsageType.Home) == null)
1177 if (!_statuses.Tabs.ContainsKey(MyCommon.DEFAULTTAB.RECENT))
1179 _statuses.AddTab(MyCommon.DEFAULTTAB.RECENT, MyCommon.TabUsageType.Home, null);
1183 _statuses.Tabs[MyCommon.DEFAULTTAB.RECENT].TabType = MyCommon.TabUsageType.Home;
1186 if (_statuses.GetTabByType(MyCommon.TabUsageType.Mentions) == null)
1188 if (!_statuses.Tabs.ContainsKey(MyCommon.DEFAULTTAB.REPLY))
1190 _statuses.AddTab(MyCommon.DEFAULTTAB.REPLY, MyCommon.TabUsageType.Mentions, null);
1194 _statuses.Tabs[MyCommon.DEFAULTTAB.REPLY].TabType = MyCommon.TabUsageType.Mentions;
1197 if (_statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage) == null)
1199 if (!_statuses.Tabs.ContainsKey(MyCommon.DEFAULTTAB.DM))
1201 _statuses.AddTab(MyCommon.DEFAULTTAB.DM, MyCommon.TabUsageType.DirectMessage, null);
1205 _statuses.Tabs[MyCommon.DEFAULTTAB.DM].TabType = MyCommon.TabUsageType.DirectMessage;
1208 if (_statuses.GetTabByType(MyCommon.TabUsageType.Favorites) == null)
1210 if (!_statuses.Tabs.ContainsKey(MyCommon.DEFAULTTAB.FAV))
1212 _statuses.AddTab(MyCommon.DEFAULTTAB.FAV, MyCommon.TabUsageType.Favorites, null);
1216 _statuses.Tabs[MyCommon.DEFAULTTAB.FAV].TabType = MyCommon.TabUsageType.Favorites;
1219 foreach (string tn in _statuses.Tabs.Keys)
1221 if (_statuses.Tabs[tn].TabType == MyCommon.TabUsageType.Undefined)
1223 _statuses.Tabs[tn].TabType = MyCommon.TabUsageType.UserDefined;
1225 if (!AddNewTab(tn, true, _statuses.Tabs[tn].TabType, _statuses.Tabs[tn].ListInfo)) throw new Exception(Properties.Resources.TweenMain_LoadText1);
1228 this.JumpReadOpMenuItem.ShortcutKeyDisplayString = "Space";
1229 CopySTOTMenuItem.ShortcutKeyDisplayString = "Ctrl+C";
1230 CopyURLMenuItem.ShortcutKeyDisplayString = "Ctrl+Shift+C";
1231 CopyUserIdStripMenuItem.ShortcutKeyDisplayString = "Shift+Alt+C";
1233 if (SettingDialog.MinimizeToTray == false || this.WindowState != FormWindowState.Minimized)
1235 this.Visible = true;
1237 _curTab = ListTab.SelectedTab;
1239 _curList = (DetailsListView)_curTab.Tag;
1240 SetMainWindowTitle();
1241 SetNotifyIconText();
1243 if (SettingDialog.TabIconDisp)
1245 ListTab.DrawMode = TabDrawMode.Normal;
1249 ListTab.DrawMode = TabDrawMode.OwnerDrawFixed;
1250 ListTab.DrawItem += ListTab_DrawItem;
1251 ListTab.ImageList = null;
1254 _ignoreConfigSave = false;
1255 this.TweenMain_Resize(null, null);
1256 if (saveRequired) SaveConfigsAll(false);
1260 tw.VerifyCredentials();
1261 foreach (UserAccount ua in _cfgCommon.UserAccounts)
1263 if (ua.Username.ToLower() == tw.Username.ToLower())
1265 ua.UserId = tw.UserId;
1270 foreach (UserAccount ua in SettingDialog.UserAccounts)
1272 if (ua.UserId == 0 && ua.Username.ToLower() == tw.Username.ToLower())
1274 ua.UserId = tw.UserId;
1281 // 初回起動時だけ右下のメニューを目立たせる
1282 HashStripSplitButton.ShowDropDown();
1289 private void CreatePictureServices()
1291 if (this.pictureService != null) this.pictureService.Clear();
1292 this.pictureService = null;
1293 this.pictureService = new Dictionary<string, IMultimediaShareService> {
1294 {"TwitPic", new TwitPic(tw)},
1295 {"img.ly", new imgly(tw)},
1296 {"yfrog", new yfrog(tw)},
1297 {"lockerz", new Plixi(tw)},
1298 {"Twitter", new TwitterPhoto(tw)}
1302 private void spaceKeyCanceler_SpaceCancel(object sender, EventArgs e)
1304 JumpUnreadMenuItem_Click(null, null);
1307 private void ListTab_DrawItem(object sender, DrawItemEventArgs e)
1312 txt = ListTab.TabPages[e.Index].Text;
1319 e.Graphics.FillRectangle(System.Drawing.SystemBrushes.Control, e.Bounds);
1320 if (e.State == DrawItemState.Selected)
1322 e.DrawFocusRectangle();
1327 if (_statuses.Tabs[txt].UnreadCount > 0)
1330 fore = System.Drawing.SystemBrushes.ControlText;
1334 fore = System.Drawing.SystemBrushes.ControlText;
1336 e.Graphics.DrawString(txt, e.Font, fore, e.Bounds, sfTab);
1339 private void LoadConfig()
1341 _cfgCommon = SettingCommon.Load();
1342 if (_cfgCommon.UserAccounts == null || _cfgCommon.UserAccounts.Count == 0)
1344 _cfgCommon.UserAccounts = new List<UserAccount>();
1345 if (!string.IsNullOrEmpty(_cfgCommon.UserName))
1347 UserAccount account = new UserAccount();
1348 account.Username = _cfgCommon.UserName;
1349 account.UserId = _cfgCommon.UserId;
1350 account.Token = _cfgCommon.Token;
1351 account.TokenSecret = _cfgCommon.TokenSecret;
1353 _cfgCommon.UserAccounts.Add(account);
1356 _cfgLocal = SettingLocal.Load();
1357 List<TabClass> tabs = SettingTabs.Load().Tabs;
1358 foreach (TabClass tb in tabs)
1362 _statuses.Tabs.Add(tb.TabName, tb);
1366 tb.TabName = _statuses.GetUniqueTabName();
1367 _statuses.Tabs.Add(tb.TabName, tb);
1370 if (_statuses.Tabs.Count == 0)
1372 _statuses.AddTab(MyCommon.DEFAULTTAB.RECENT, MyCommon.TabUsageType.Home, null);
1373 _statuses.AddTab(MyCommon.DEFAULTTAB.REPLY, MyCommon.TabUsageType.Mentions, null);
1374 _statuses.AddTab(MyCommon.DEFAULTTAB.DM, MyCommon.TabUsageType.DirectMessage, null);
1375 _statuses.AddTab(MyCommon.DEFAULTTAB.FAV, MyCommon.TabUsageType.Favorites, null);
1379 private void TimerInterval_Changed(object sender, AppendSettingDialog.IntervalChangedEventArgs e) //Handles SettingDialog.IntervalChanged
1381 if (!TimerTimeline.Enabled) return;
1385 private AppendSettingDialog.IntervalChangedEventArgs ResetTimers = new AppendSettingDialog.IntervalChangedEventArgs();
1387 private static int homeCounter = 0;
1388 private static int mentionCounter = 0;
1389 private static int dmCounter = 0;
1390 private static int pubSearchCounter = 0;
1391 private static int userTimelineCounter = 0;
1392 private static int listsCounter = 0;
1393 private static int usCounter = 0;
1394 private static int ResumeWait = 0;
1395 private static int refreshFollowers = 0;
1397 private void TimerTimeline_Elapsed(object sender, EventArgs e)
1399 if (homeCounter > 0) Interlocked.Decrement(ref homeCounter);
1400 if (mentionCounter > 0) Interlocked.Decrement(ref mentionCounter);
1401 if (dmCounter > 0) Interlocked.Decrement(ref dmCounter);
1402 if (pubSearchCounter > 0) Interlocked.Decrement(ref pubSearchCounter);
1403 if (userTimelineCounter > 0) Interlocked.Decrement(ref userTimelineCounter);
1404 if (listsCounter > 0) Interlocked.Decrement(ref listsCounter);
1405 if (usCounter > 0) Interlocked.Decrement(ref usCounter);
1406 Interlocked.Increment(ref refreshFollowers);
1409 if (ResetTimers.Timeline || homeCounter <= 0 && SettingDialog.TimelinePeriodInt > 0)
1411 Interlocked.Exchange(ref homeCounter, SettingDialog.TimelinePeriodInt);
1412 if (!tw.IsUserstreamDataReceived && !ResetTimers.Timeline) GetTimeline(MyCommon.WORKERTYPE.Timeline, 1, 0, "");
1413 ResetTimers.Timeline = false;
1415 if (ResetTimers.Reply || mentionCounter <= 0 && SettingDialog.ReplyPeriodInt > 0)
1417 Interlocked.Exchange(ref mentionCounter, SettingDialog.ReplyPeriodInt);
1418 if (!tw.IsUserstreamDataReceived && !ResetTimers.Reply) GetTimeline(MyCommon.WORKERTYPE.Reply, 1, 0, "");
1419 ResetTimers.Reply = false;
1421 if (ResetTimers.DirectMessage || dmCounter <= 0 && SettingDialog.DMPeriodInt > 0)
1423 Interlocked.Exchange(ref dmCounter, SettingDialog.DMPeriodInt);
1424 if (!tw.IsUserstreamDataReceived && !ResetTimers.DirectMessage) GetTimeline(MyCommon.WORKERTYPE.DirectMessegeRcv, 1, 0, "");
1425 ResetTimers.DirectMessage = false;
1427 if (ResetTimers.PublicSearch || pubSearchCounter <= 0 && SettingDialog.PubSearchPeriodInt > 0)
1429 Interlocked.Exchange(ref pubSearchCounter, SettingDialog.PubSearchPeriodInt);
1430 if (!ResetTimers.PublicSearch) GetTimeline(MyCommon.WORKERTYPE.PublicSearch, 1, 0, "");
1431 ResetTimers.PublicSearch = false;
1433 if (ResetTimers.UserTimeline || userTimelineCounter <= 0 && SettingDialog.UserTimelinePeriodInt > 0)
1435 Interlocked.Exchange(ref userTimelineCounter, SettingDialog.UserTimelinePeriodInt);
1436 if (!ResetTimers.UserTimeline) GetTimeline(MyCommon.WORKERTYPE.UserTimeline, 1, 0, "");
1437 ResetTimers.UserTimeline = false;
1439 if (ResetTimers.Lists || listsCounter <= 0 && SettingDialog.ListsPeriodInt > 0)
1441 Interlocked.Exchange(ref listsCounter, SettingDialog.ListsPeriodInt);
1442 if (!ResetTimers.Lists) GetTimeline(MyCommon.WORKERTYPE.List, 1, 0, "");
1443 ResetTimers.Lists = false;
1445 if (ResetTimers.UserStream || usCounter <= 0 && SettingDialog.UserstreamPeriodInt > 0)
1447 Interlocked.Exchange(ref usCounter, SettingDialog.UserstreamPeriodInt);
1448 if (this._isActiveUserstream) RefreshTimeline(true);
1449 ResetTimers.UserStream = false;
1451 if (refreshFollowers > 6 * 3600)
1453 Interlocked.Exchange(ref refreshFollowers, 0);
1454 doGetFollowersMenu();
1455 GetTimeline(MyCommon.WORKERTYPE.Configuration, 0, 0, "");
1456 if (InvokeRequired && !IsDisposed) this.Invoke(new MethodInvoker(this.TrimPostChain));
1460 Interlocked.Increment(ref ResumeWait);
1461 if (ResumeWait > 30)
1464 Interlocked.Exchange(ref ResumeWait, 0);
1465 GetTimeline(MyCommon.WORKERTYPE.Timeline, 1, 0, "");
1466 GetTimeline(MyCommon.WORKERTYPE.Reply, 1, 0, "");
1467 GetTimeline(MyCommon.WORKERTYPE.DirectMessegeRcv, 1, 0, "");
1468 GetTimeline(MyCommon.WORKERTYPE.PublicSearch, 1, 0, "");
1469 GetTimeline(MyCommon.WORKERTYPE.UserTimeline, 1, 0, "");
1470 GetTimeline(MyCommon.WORKERTYPE.List, 1, 0, "");
1471 doGetFollowersMenu();
1472 GetTimeline(MyCommon.WORKERTYPE.Configuration, 0, 0, "");
1473 if (InvokeRequired && !IsDisposed) this.Invoke(new MethodInvoker(this.TrimPostChain));
1478 private void RefreshTimeline(bool isUserStream)
1480 if (isUserStream) this.RefreshTasktrayIcon(true);
1482 int smode = -1; //-1:制御しない,-2:最新へ,その他:topitem使用
1483 long topId = GetScrollPos(ref smode);
1484 int befCnt = _curList.VirtualListSize;
1487 Dictionary<string, long[]> selId = new Dictionary<string, long[]>();
1488 Dictionary<string, long> focusedId = new Dictionary<string, long>();
1489 SaveSelectedStatus(selId, focusedId);
1492 int dmCount = _statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage).AllCount;
1495 PostClass[] notifyPosts = null;
1496 string soundFile = "";
1498 bool isMention = false;
1499 bool isDelete = false;
1500 addCount = _statuses.SubmitUpdate(ref soundFile, ref notifyPosts, ref isMention, ref isDelete, isUserStream);
1502 if (MyCommon._endingFlag) return;
1507 foreach (TabPage tab in ListTab.TabPages)
1509 DetailsListView lst = (DetailsListView)tab.Tag;
1510 TabClass tabInfo = _statuses.Tabs[tab.Text];
1512 if (isDelete || lst.VirtualListSize != tabInfo.AllCount)
1514 if (lst.Equals(_curList))
1516 this.PurgeListViewItemCache();
1520 lst.VirtualListSize = tabInfo.AllCount; //リスト件数更新
1526 this.SelectListItem(lst,
1527 _statuses.IndexOf(tab.Text, selId[tab.Text]),
1528 _statuses.IndexOf(tab.Text, focusedId[tab.Text]));
1531 if (tabInfo.UnreadCount > 0)
1532 if (SettingDialog.TabIconDisp)
1533 if (tab.ImageIndex == -1) tab.ImageIndex = 0; //タブアイコン
1535 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
1539 //ex.Data["Msg"] = "Ref1, UseAPI=" + SettingDialog.UseAPI.ToString();
1548 if (befCnt != _curList.VirtualListSize)
1554 if (_curList.VirtualListSize > 0) _curList.EnsureVisible(0);
1558 if (_curList.VirtualListSize > 0) _curList.EnsureVisible(_curList.VirtualListSize - 1);
1565 if (_curList.VirtualListSize > 0 && _statuses.IndexOf(_curTab.Text, topId) > -1)
1567 _curList.EnsureVisible(_curList.VirtualListSize - 1);
1568 _curList.EnsureVisible(_statuses.IndexOf(_curTab.Text, topId));
1574 catch (Exception ex)
1576 ex.Data["Msg"] = "Ref2";
1582 NotifyNewPosts(notifyPosts,
1585 isMention || dmCount != _statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage).AllCount);
1587 SetMainWindowTitle();
1588 if (!StatusLabelUrl.Text.StartsWith("http")) SetStatusLabelUrl();
1590 HashSupl.AddRangeItem(tw.GetHashList());
1594 private long GetScrollPos(ref int smode)
1597 if (_curList != null && _curTab != null && _curList.VirtualListSize > 0)
1599 if (_statuses.SortMode == IdComparerClass.ComparerMode.Id)
1601 if (_statuses.SortOrder == SortOrder.Ascending)
1604 if (ListLockMenuItem.Checked)
1609 //if (_curList.TopItem != null) topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index);
1614 //最下行が表示されていたら、最下行へ強制スクロール。最下行が表示されていなかったら制御しない
1616 _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1); //一番下
1617 if (_item == null) _item = _curList.Items[_curList.Items.Count - 1];
1618 if (_item.Index == _curList.Items.Count - 1)
1625 //if (_curList.TopItem != null) topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index);
1633 if (ListLockMenuItem.Checked)
1636 if (_curList.TopItem != null) topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index);
1641 //最上行が表示されていたら、制御しない。最上行が表示されていなかったら、現在表示位置へ強制スクロール
1644 _item = _curList.GetItemAt(0, 10); //一番上
1645 if (_item == null) _item = _curList.Items[0];
1646 if (_item.Index == 0)
1652 if (_curList.TopItem != null) topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index);
1661 if (_curList.TopItem != null) topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index);
1672 private void SaveSelectedStatus(Dictionary<string, long[]> selId, Dictionary<string, long> focusedId)
1674 if (MyCommon._endingFlag) return;
1675 foreach (TabPage tab in ListTab.TabPages)
1677 DetailsListView lst = (DetailsListView)tab.Tag;
1678 if (lst.SelectedIndices.Count > 0 && lst.SelectedIndices.Count < 61)
1680 selId.Add(tab.Text, _statuses.GetId(tab.Text, lst.SelectedIndices));
1684 selId.Add(tab.Text, new long[1] {-2});
1686 if (lst.FocusedItem != null)
1687 focusedId.Add(tab.Text, _statuses.GetId(tab.Text, lst.FocusedItem.Index));
1689 focusedId.Add(tab.Text, -2);
1694 private bool BalloonRequired()
1696 Twitter.FormattedEvent ev = new Twitter.FormattedEvent();
1697 ev.Eventtype = MyCommon.EVENTTYPE.None;
1699 return BalloonRequired(ev);
1702 private bool IsEventNotifyAsEventType(MyCommon.EVENTTYPE type)
1704 return SettingDialog.EventNotifyEnabled && (type & SettingDialog.EventNotifyFlag) != 0 || type == MyCommon.EVENTTYPE.None;
1707 private bool IsMyEventNotityAsEventType(Twitter.FormattedEvent ev)
1709 return (ev.Eventtype & SettingDialog.IsMyEventNotifyFlag) != 0 ? true : !ev.IsMe;
1712 private bool BalloonRequired(Twitter.FormattedEvent ev)
1715 IsEventNotifyAsEventType(ev.Eventtype) && IsMyEventNotityAsEventType(ev) &&
1716 (NewPostPopMenuItem.Checked || (SettingDialog.ForceEventNotify && ev.Eventtype != MyCommon.EVENTTYPE.None)) &&
1720 SettingDialog.LimitBalloon &&
1722 this.WindowState == FormWindowState.Minimized ||
1724 Form.ActiveForm == null
1727 !SettingDialog.LimitBalloon
1730 !Win32Api.IsScreenSaverRunning())
1740 private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCount, bool newMentions)
1742 if (notifyPosts != null &&
1743 notifyPosts.Length > 0 &&
1744 this.SettingDialog.ReadOwnPost &&
1745 notifyPosts.All((post) => { return post.UserId == tw.UserId || post.ScreenName == tw.Username; }))
1751 if (BalloonRequired())
1753 if (notifyPosts != null && notifyPosts.Length > 0)
1755 //Growlは一個ずつばらして通知。ただし、3ポスト以上あるときはまとめる
1756 if (SettingDialog.IsNotifyUseGrowl)
1758 StringBuilder sb = new StringBuilder();
1762 foreach (PostClass post in notifyPosts)
1764 if (!(notifyPosts.Length > 3))
1770 if (post.IsReply && !post.IsExcludeReply) reply = true;
1771 if (post.IsDm) dm = true;
1772 if (sb.Length > 0) sb.Append(System.Environment.NewLine);
1773 switch (SettingDialog.NameBalloon)
1775 case MyCommon.NameBalloonEnum.UserID:
1776 sb.Append(post.ScreenName).Append(" : ");
1778 case MyCommon.NameBalloonEnum.NickName:
1779 sb.Append(post.Nickname).Append(" : ");
1782 sb.Append(post.TextFromApi);
1783 if (notifyPosts.Length > 3)
1785 if (notifyPosts.Last() != post) continue;
1788 StringBuilder title = new StringBuilder();
1789 GrowlHelper.NotifyType nt;
1790 if (SettingDialog.DispUsername)
1792 title.Append(tw.Username);
1793 title.Append(" - ");
1801 //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
1802 //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [DM] " + Properties.Resources.RefreshDirectMessageText1 + " " + addCount.ToString() + Properties.Resources.RefreshDirectMessageText2;
1803 title.Append(Application.ProductName);
1804 title.Append(" [DM] ");
1805 title.Append(Properties.Resources.RefreshDirectMessageText1);
1807 title.Append(addCount);
1808 title.Append(Properties.Resources.RefreshDirectMessageText2);
1809 nt = GrowlHelper.NotifyType.DirectMessage;
1813 //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
1814 //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [Reply!] " + Properties.Resources.RefreshTimelineText1 + " " + addCount.ToString() + Properties.Resources.RefreshTimelineText2;
1815 title.Append(Application.ProductName);
1816 title.Append(" [Reply!] ");
1817 title.Append(Properties.Resources.RefreshTimelineText1);
1819 title.Append(addCount);
1820 title.Append(Properties.Resources.RefreshTimelineText2);
1821 nt = GrowlHelper.NotifyType.Reply;
1825 //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info;
1826 //NotifyIcon1.BalloonTipTitle += Application.ProductName + " " + Properties.Resources.RefreshTimelineText1 + " " + addCount.ToString() + Properties.Resources.RefreshTimelineText2;
1827 title.Append(Application.ProductName);
1829 title.Append(Properties.Resources.RefreshTimelineText1);
1831 title.Append(addCount);
1832 title.Append(Properties.Resources.RefreshTimelineText2);
1833 nt = GrowlHelper.NotifyType.Notify;
1835 string bText = sb.ToString();
1836 if (string.IsNullOrEmpty(bText)) return;
1838 var image = this.IconCache.TryGetFromCache(post.ImageUrl);
1839 gh.Notify(nt, post.StatusId.ToString(), title.ToString(), bText, image == null ? null : image.Image, post.ImageUrl);
1844 StringBuilder sb = new StringBuilder();
1847 foreach (PostClass post in notifyPosts)
1849 if (post.IsReply && !post.IsExcludeReply) reply = true;
1850 if (post.IsDm) dm = true;
1851 if (sb.Length > 0) sb.Append(System.Environment.NewLine);
1852 switch (SettingDialog.NameBalloon)
1854 case MyCommon.NameBalloonEnum.UserID:
1855 sb.Append(post.ScreenName).Append(" : ");
1857 case MyCommon.NameBalloonEnum.NickName:
1858 sb.Append(post.Nickname).Append(" : ");
1861 sb.Append(post.TextFromApi);
1864 //if (SettingDialog.DispUsername) { NotifyIcon1.BalloonTipTitle = tw.Username + " - "; } else { NotifyIcon1.BalloonTipTitle = ""; }
1865 StringBuilder title = new StringBuilder();
1867 if (SettingDialog.DispUsername)
1869 title.Append(tw.Username);
1870 title.Append(" - ");
1878 //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
1879 //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [DM] " + Properties.Resources.RefreshDirectMessageText1 + " " + addCount.ToString() + Properties.Resources.RefreshDirectMessageText2;
1880 ntIcon = ToolTipIcon.Warning;
1881 title.Append(Application.ProductName);
1882 title.Append(" [DM] ");
1883 title.Append(Properties.Resources.RefreshDirectMessageText1);
1885 title.Append(addCount);
1886 title.Append(Properties.Resources.RefreshDirectMessageText2);
1890 //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
1891 //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [Reply!] " + Properties.Resources.RefreshTimelineText1 + " " + addCount.ToString() + Properties.Resources.RefreshTimelineText2;
1892 ntIcon = ToolTipIcon.Warning;
1893 title.Append(Application.ProductName);
1894 title.Append(" [Reply!] ");
1895 title.Append(Properties.Resources.RefreshTimelineText1);
1897 title.Append(addCount);
1898 title.Append(Properties.Resources.RefreshTimelineText2);
1902 //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info;
1903 //NotifyIcon1.BalloonTipTitle += Application.ProductName + " " + Properties.Resources.RefreshTimelineText1 + " " + addCount.ToString() + Properties.Resources.RefreshTimelineText2;
1904 ntIcon = ToolTipIcon.Info;
1905 title.Append(Application.ProductName);
1907 title.Append(Properties.Resources.RefreshTimelineText1);
1909 title.Append(addCount);
1910 title.Append(Properties.Resources.RefreshTimelineText2);
1912 string bText = sb.ToString();
1913 if (string.IsNullOrEmpty(bText)) return;
1914 //NotifyIcon1.BalloonTipText = sb.ToString();
1915 //NotifyIcon1.ShowBalloonTip(500);
1916 NotifyIcon1.BalloonTipTitle = title.ToString();
1917 NotifyIcon1.BalloonTipText = bText;
1918 NotifyIcon1.BalloonTipIcon = ntIcon;
1919 NotifyIcon1.ShowBalloonTip(500);
1925 if (!_initial && SettingDialog.PlaySound && !string.IsNullOrEmpty(soundFile))
1929 string dir = Application.StartupPath;
1930 if (Directory.Exists(Path.Combine(dir, "Sounds")))
1932 dir = Path.Combine(dir, "Sounds");
1934 using (SoundPlayer player = new SoundPlayer(Path.Combine(dir, soundFile)))
1944 //mentions新着時に画面ブリンク
1945 if (!_initial && SettingDialog.BlinkNewMentions && newMentions && Form.ActiveForm == null)
1947 Win32Api.FlashMyWindow(this.Handle, Win32Api.FlashSpecification.FlashTray, 3);
1951 private void MyList_SelectedIndexChanged(object sender, EventArgs e)
1953 if (_curList == null || _curList.SelectedIndices.Count != 1) return;
1955 _curItemIndex = _curList.SelectedIndices[0];
1956 if (_curItemIndex > _curList.VirtualListSize - 1) return;
1960 _curPost = GetCurTabPost(_curItemIndex);
1962 catch (ArgumentException)
1967 this.PushSelectPostChain();
1969 if (SettingDialog.UnreadManage) _statuses.SetReadAllTab(true, _curTab.Text, _curItemIndex);
1971 ChangeCacheStyleRead(true, _curItemIndex, _curTab); //既読へ(フォント、文字色)
1977 private void ChangeCacheStyleRead(bool Read, int Index, TabPage Tab)
1979 //Read:true=既読 false=未読
1980 //未読管理していなかったら既読として扱う
1981 if (!_statuses.Tabs[_curTab.Text].UnreadManage ||
1982 !SettingDialog.UnreadManage) Read = true;
1985 ListViewItem itm = null;
1986 PostClass post = null;
1988 if (Tab.Equals(this._curTab))
1990 this.TryGetListViewItemCache(Index, out itm, out post);
1993 if (itm == null || post == null)
1995 itm = ((DetailsListView)Tab.Tag).Items[Index];
1996 post = _statuses[Tab.Text, Index];
1999 ChangeItemStyleRead(Read, itm, post, ((DetailsListView)Tab.Tag));
2002 private void ChangeItemStyleRead(bool Read, ListViewItem Item, PostClass Post, DetailsListView DList)
2009 Item.SubItems[5].Text = "";
2014 Item.SubItems[5].Text = "★";
2020 else if (Post.RetweetedId > 0)
2022 else if (Post.IsOwl && (Post.IsDm || SettingDialog.OneWayLove))
2024 else if (Read || !SettingDialog.UseUnreadStyle)
2029 if (DList == null || Item.Index == -1)
2031 Item.ForeColor = cl;
2032 if (SettingDialog.UseUnreadStyle)
2038 if (SettingDialog.UseUnreadStyle)
2039 DList.ChangeItemFontAndColor(Item.Index, cl, fnt);
2041 DList.ChangeItemForeColor(Item.Index, cl);
2042 //if (_itemCache != null) DList.RedrawItems(_itemCacheIndex, _itemCacheIndex + _itemCache.Length - 1, false);
2046 private void ColorizeList()
2048 //Index:更新対象のListviewItem.Index。Colorを返す。
2049 //-1は全キャッシュ。Colorは返さない(ダミーを戻す)
2052 _post = _anchorPost;
2056 if (_post == null) return;
2058 var itemColorTuple = new Tuple<ListViewItem, Color>[] { };
2060 this.itemCacheLock.EnterReadLock();
2063 if (this._itemCache == null) return;
2066 from i in Enumerable.Range(0, this._itemCache.Length)
2067 select new Tuple<ListViewItem, Color>(this._itemCache[i], this.JudgeColor(_post, this._postCache[i]));
2069 itemColorTuple = query.ToArray();
2071 finally { this.itemCacheLock.ExitReadLock(); }
2073 foreach (var tuple in itemColorTuple)
2075 // この処理中に MyList_CacheVirtualItems が呼ばれることがあるため、
2076 // 同一スレッド内での二重ロックを避けるためにロックの外で実行する必要がある
2077 tuple.Item1.SubItems[0].BackColor = tuple.Item2;
2081 private void ColorizeList(ListViewItem Item, int Index)
2083 //Index:更新対象のListviewItem.Index。Colorを返す。
2084 //-1は全キャッシュ。Colorは返さない(ダミーを戻す)
2087 _post = _anchorPost;
2091 PostClass tPost = GetCurTabPost(Index);
2093 if (_post == null) return;
2095 if (Item.Index == -1)
2096 Item.BackColor = JudgeColor(_post, tPost);
2098 _curList.ChangeItemBackColor(Item.Index, JudgeColor(_post, tPost));
2101 private Color JudgeColor(PostClass BasePost, PostClass TargetPost)
2104 if (TargetPost.StatusId == BasePost.InReplyToStatusId)
2107 else if (TargetPost.IsMe)
2110 else if (TargetPost.IsReply)
2113 else if (BasePost.ReplyToList.Contains(TargetPost.ScreenName.ToLower()))
2115 cl = _clAtFromTarget;
2116 else if (TargetPost.ReplyToList.Contains(BasePost.ScreenName.ToLower()))
2119 else if (TargetPost.ScreenName.Equals(BasePost.ScreenName, StringComparison.OrdinalIgnoreCase))
2124 cl = _clListBackcolor;
2129 private void PostButton_Click(object sender, EventArgs e)
2131 if (StatusText.Text.Trim().Length == 0)
2133 if (!ImageSelectionPanel.Enabled)
2140 if (this.ExistCurrentPost && StatusText.Text.Trim() == string.Format("RT @{0}: {1}", _curPost.ScreenName, _curPost.TextFromApi))
2142 DialogResult rtResult = MessageBox.Show(string.Format(Properties.Resources.PostButton_Click1, Environment.NewLine),
2144 MessageBoxButtons.YesNoCancel,
2145 MessageBoxIcon.Question);
2148 case DialogResult.Yes:
2149 doReTweetOfficial(false);
2150 StatusText.Text = "";
2152 case DialogResult.Cancel:
2157 _history[_history.Count - 1] = new PostingStatus(StatusText.Text.Trim(), _reply_to_id, _reply_to_name);
2159 if (SettingDialog.Nicoms)
2161 StatusText.SelectionStart = StatusText.Text.Length;
2162 UrlConvert(MyCommon.UrlConverter.Nicoms);
2164 //if (SettingDialog.UrlConvertAuto)
2166 // StatusText.SelectionStart = StatusText.Text.Length;
2167 // UrlConvertAutoToolStripMenuItem_Click(null, null);
2169 //else if (SettingDialog.Nicoms)
2171 // StatusText.SelectionStart = StatusText.Text.Length;
2172 // UrlConvert(UrlConverter.Nicoms);
2174 StatusText.SelectionStart = StatusText.Text.Length;
2175 GetWorkerArg args = new GetWorkerArg();
2178 args.type = MyCommon.WORKERTYPE.PostMessage;
2179 CheckReplyTo(StatusText.Text);
2182 int adjustCount = 0;
2183 string tmpStatus = StatusText.Text.Trim();
2184 if (ToolStripMenuItemApiCommandEvasion.Checked)
2187 if (Regex.IsMatch(tmpStatus,
2188 @"^[+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]*(get|g|fav|follow|f|on|off|stop|quit|leave|l|whois|w|nudge|n|stats|invite|track|untrack|tracks|tracking|\*)([+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]+|$)",
2189 RegexOptions.IgnoreCase)
2190 && tmpStatus.EndsWith(" .") == false) adjustCount += 2;
2193 if (ToolStripMenuItemUrlMultibyteSplit.Checked)
2196 adjustCount += Regex.Matches(tmpStatus, @"https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#^]+").Count;
2199 bool isCutOff = false;
2200 bool isRemoveFooter = MyCommon.IsKeyDown(Keys.Shift);
2201 if (StatusText.Multiline && !SettingDialog.PostCtrlEnter)
2203 //複数行でEnter投稿の場合、Ctrlも押されていたらフッタ付加しない
2204 isRemoveFooter = MyCommon.IsKeyDown(Keys.Control);
2206 if (SettingDialog.PostShiftEnter)
2208 isRemoveFooter = MyCommon.IsKeyDown(Keys.Control);
2210 if (!isRemoveFooter && (StatusText.Text.Contains("RT @") || StatusText.Text.Contains("QT @")))
2212 isRemoveFooter = true;
2214 if (GetRestStatusCount(false, !isRemoveFooter) - adjustCount < 0)
2216 if (MessageBox.Show(Properties.Resources.PostLengthOverMessage1, Properties.Resources.PostLengthOverMessage2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.OK)
2219 //if (!SettingDialog.UrlConvertAuto) UrlConvertAutoToolStripMenuItem_Click(null, null);
2220 if (GetRestStatusCount(false, !isRemoveFooter) - adjustCount < 0)
2222 isRemoveFooter = true;
2233 if (StatusText.Text.StartsWith("D ") || StatusText.Text.StartsWith("d "))
2241 if (HashMgr.IsNotAddToAtReply)
2243 if (!string.IsNullOrEmpty(HashMgr.UseHash) && _reply_to_id == 0 && string.IsNullOrEmpty(_reply_to_name))
2246 header = HashMgr.UseHash + " ";
2248 footer = " " + HashMgr.UseHash;
2253 if (!string.IsNullOrEmpty(HashMgr.UseHash))
2256 header = HashMgr.UseHash + " ";
2258 footer = " " + HashMgr.UseHash;
2261 if (!isRemoveFooter)
2263 if (SettingDialog.UseRecommendStatus)
2265 footer += SettingDialog.RecommendStatusText;
2267 // テキストボックスに入力されている文字列を使用する
2268 footer += " " + SettingDialog.Status.Trim();
2271 args.status.status = header + StatusText.Text.Trim() + footer;
2273 if (ToolStripMenuItemApiCommandEvasion.Checked)
2276 if (Regex.IsMatch(args.status.status,
2277 @"^[+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]*(get|g|fav|follow|f|on|off|stop|quit|leave|l|whois|w|nudge|n|stats|invite|track|untrack|tracks|tracking|\*)([+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]+|$)",
2278 RegexOptions.IgnoreCase)
2279 && args.status.status.EndsWith(" .") == false) args.status.status += " .";
2282 if (ToolStripMenuItemUrlMultibyteSplit.Checked)
2285 Match mc2 = Regex.Match(args.status.status, @"https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#^]+");
2286 if (mc2.Success) args.status.status = Regex.Replace(args.status.status, @"https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#^]+", "$& ");
2289 if (IdeographicSpaceToSpaceToolStripMenuItem.Checked)
2291 // 文中の全角スペースを半角スペース1個にする
2292 args.status.status = args.status.status.Replace(" ", " ");
2295 if (isCutOff && args.status.status.Length > 140)
2297 args.status.status = args.status.status.Substring(0, 140);
2298 string AtId = @"(@|@)[a-z0-9_/]+$";
2299 string HashTag = @"(^|[^0-9A-Z&\/\?]+)(#|#)([0-9A-Z_]*[A-Z_]+)$";
2300 string Url = @"https?:\/\/[a-z0-9!\*'\(\);:&=\+\$\/%#\[\]\-_\.,~?]+$"; //簡易判定
2301 string pattern = string.Format("({0})|({1})|({2})", AtId, HashTag, Url);
2302 Match mc = Regex.Match(args.status.status, pattern, RegexOptions.IgnoreCase);
2305 //さらに@ID、ハッシュタグ、URLと推測される文字列をカットする
2306 args.status.status = args.status.status.Substring(0, 140 - mc.Value.Length);
2308 if (MessageBox.Show(args.status.status, "Post or Cancel?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel) return;
2311 args.status.inReplyToId = _reply_to_id;
2312 args.status.inReplyToName = _reply_to_name;
2313 if (ImageSelectionPanel.Visible)
2316 if (ImageSelectedPicture.Image != ImageSelectedPicture.InitialImage &&
2317 ImageServiceCombo.SelectedIndex > -1 &&
2318 !string.IsNullOrEmpty(ImagefilePathText.Text))
2320 if (MessageBox.Show(Properties.Resources.PostPictureConfirm1,
2321 Properties.Resources.PostPictureConfirm2,
2322 MessageBoxButtons.OKCancel,
2323 MessageBoxIcon.Question,
2324 MessageBoxDefaultButton.Button1)
2325 == DialogResult.Cancel)
2327 TimelinePanel.Visible = true;
2328 TimelinePanel.Enabled = true;
2329 ImageSelectionPanel.Visible = false;
2330 ImageSelectionPanel.Enabled = false;
2331 if (_curList != null)
2335 args.status.imageService = ImageServiceCombo.Text;
2336 args.status.imagePath = ImagefilePathText.Text;
2337 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
2338 ImagefilePathText.Text = "";
2339 TimelinePanel.Visible = true;
2340 TimelinePanel.Enabled = true;
2341 ImageSelectionPanel.Visible = false;
2342 ImageSelectionPanel.Enabled = false;
2343 if (_curList != null)
2348 MessageBox.Show(Properties.Resources.PostPictureWarn1, Properties.Resources.PostPictureWarn2);
2356 if (StatusText.Text.StartsWith("Google:", StringComparison.OrdinalIgnoreCase) && StatusText.Text.Trim().Length > 7)
2358 string tmp = string.Format(Properties.Resources.SearchItem2Url, Uri.EscapeUriString(StatusText.Text.Substring(7)));
2363 _reply_to_name = "";
2364 StatusText.Text = "";
2365 _history.Add(new PostingStatus());
2366 _hisIdx = _history.Count - 1;
2367 if (!ToolStripFocusLockMenuItem.Checked)
2368 ((Control)ListTab.SelectedTab.Tag).Focus();
2369 urlUndoBuffer = null;
2370 UrlUndoToolStripMenuItem.Enabled = false; //Undoをできないように設定
2373 private void EndToolStripMenuItem_Click(object sender, EventArgs e)
2375 MyCommon._endingFlag = true;
2379 private void Tween_FormClosing(object sender, FormClosingEventArgs e)
2381 if (!SettingDialog.CloseToExit && e.CloseReason == CloseReason.UserClosing && MyCommon._endingFlag == false)
2383 //_endingFlag=false:フォームの×ボタン
2385 this.Visible = false;
2389 //Google.GASender.GetInstance().TrackEventWithCategory("post", "end", tw.UserId);
2390 _hookGlobalHotkey.UnregisterAllOriginalHotkey();
2391 _ignoreConfigSave = true;
2392 MyCommon._endingFlag = true;
2393 TimerTimeline.Enabled = false;
2394 TimerRefreshIcon.Enabled = false;
2398 private void NotifyIcon1_BalloonTipClicked(object sender, EventArgs e)
2400 this.Visible = true;
2401 if (this.WindowState == FormWindowState.Minimized)
2403 this.WindowState = FormWindowState.Normal;
2406 this.BringToFront();
2409 private static int errorCount = 0;
2411 private static bool CheckAccountValid()
2413 if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid)
2419 Twitter.AccountState = MyCommon.ACCOUNT_STATE.Valid;
2428 private void GetTimelineWorker_DoWork(object sender, DoWorkEventArgs e)
2430 BackgroundWorker bw = (BackgroundWorker)sender;
2431 if (bw.CancellationPending || MyCommon._endingFlag)
2437 Thread.CurrentThread.Priority = ThreadPriority.BelowNormal;
2439 MyApplication.InitCulture();
2442 GetWorkerResult rslt = new GetWorkerResult();
2444 bool read = !SettingDialog.UnreadManage;
2445 if (_initial && SettingDialog.UnreadManage) read = SettingDialog.Readed;
2447 GetWorkerArg args = (GetWorkerArg)e.Argument;
2449 if (!CheckAccountValid())
2451 rslt.retMsg = "Auth error. Check your account";
2452 rslt.type = MyCommon.WORKERTYPE.ErrorState; //エラー表示のみ行ない、後処理キャンセル
2453 rslt.tName = args.tName;
2458 bw.ReportProgress(0, ""); //Notifyアイコンアニメーション開始
2462 case MyCommon.WORKERTYPE.Timeline:
2463 case MyCommon.WORKERTYPE.Reply:
2464 bw.ReportProgress(50, MakeStatusMessage(args, false));
2465 ret = tw.GetTimelineApi(read, args.type, args.page == -1, _initial);
2467 if (string.IsNullOrEmpty(ret) && args.type == MyCommon.WORKERTYPE.Timeline && SettingDialog.ReadOldPosts)
2468 _statuses.SetRead();
2470 rslt.addCount = _statuses.DistributePosts();
2472 case MyCommon.WORKERTYPE.DirectMessegeRcv: //送信分もまとめて取得
2473 bw.ReportProgress(50, MakeStatusMessage(args, false));
2474 ret = tw.GetDirectMessageApi(read, MyCommon.WORKERTYPE.DirectMessegeRcv, args.page == -1);
2475 if (string.IsNullOrEmpty(ret)) ret = tw.GetDirectMessageApi(read, MyCommon.WORKERTYPE.DirectMessegeSnt, args.page == -1);
2476 rslt.addCount = _statuses.DistributePosts();
2478 case MyCommon.WORKERTYPE.FavAdd:
2480 if (_statuses.Tabs.ContainsKey(args.tName))
2482 TabClass tbc = _statuses.Tabs[args.tName];
2483 for (int i = 0; i <= args.ids.Count - 1; i++)
2485 PostClass post = null;
2486 if (tbc.IsInnerStorageTabType)
2487 post = tbc.Posts[args.ids[i]];
2489 post = _statuses[args.ids[i]];
2492 bw.ReportProgress(50, MakeStatusMessage(args, false));
2495 if (post.RetweetedId == 0)
2496 ret = tw.PostFavAdd(post.StatusId);
2498 ret = tw.PostFavAdd(post.RetweetedId);
2500 if (ret.Length == 0)
2502 args.sIds.Add(post.StatusId);
2503 post.IsFav = true; //リスト再描画必要
2504 _favTimestamps.Add(DateTime.Now);
2505 if (string.IsNullOrEmpty(post.RelTabName))
2507 //検索,リストUserTimeline.Relatedタブからのfavは、favタブへ追加せず。それ以外は追加
2508 _statuses.GetTabByType(MyCommon.TabUsageType.Favorites).Add(post.StatusId, post.IsRead, false);
2512 //検索,リスト,UserTimeline.Relatedタブからのfavで、TLでも取得済みならfav反映
2513 if (_statuses.ContainsKey(post.StatusId))
2515 PostClass postTl = _statuses[post.StatusId];
2516 postTl.IsFav = true;
2517 _statuses.GetTabByType(MyCommon.TabUsageType.Favorites).Add(postTl.StatusId, postTl.IsRead, false);
2520 //検索,リスト,UserTimeline,Relatedの各タブに反映
2521 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.PublicSearch | MyCommon.TabUsageType.Lists | MyCommon.TabUsageType.UserTimeline | MyCommon.TabUsageType.Related))
2523 if (tb.Contains(post.StatusId)) tb.Posts[post.StatusId].IsFav = true;
2529 rslt.sIds = args.sIds;
2531 case MyCommon.WORKERTYPE.FavRemove:
2533 if (_statuses.Tabs.ContainsKey(args.tName))
2535 TabClass tbc = _statuses.Tabs[args.tName];
2536 for (int i = 0; i <= args.ids.Count - 1; i++)
2538 PostClass post = null;
2539 if (tbc.IsInnerStorageTabType)
2540 post = tbc.Posts[args.ids[i]];
2542 post = _statuses[args.ids[i]];
2545 bw.ReportProgress(50, MakeStatusMessage(args, false));
2548 if (post.RetweetedId == 0)
2549 ret = tw.PostFavRemove(post.StatusId);
2551 ret = tw.PostFavRemove(post.RetweetedId);
2553 if (ret.Length == 0)
2555 args.sIds.Add(post.StatusId);
2556 post.IsFav = false; //リスト再描画必要
2557 if (_statuses.ContainsKey(post.StatusId)) _statuses[post.StatusId].IsFav = false;
2558 //検索,リスト,UserTimeline,Relatedの各タブに反映
2559 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.PublicSearch | MyCommon.TabUsageType.Lists | MyCommon.TabUsageType.UserTimeline | MyCommon.TabUsageType.Related))
2561 if (tb.Contains(post.StatusId)) tb.Posts[post.StatusId].IsFav = false;
2567 rslt.sIds = args.sIds;
2569 case MyCommon.WORKERTYPE.PostMessage:
2570 bw.ReportProgress(200);
2571 if (string.IsNullOrEmpty(args.status.imagePath))
2573 for (int i = 0; i <= 1; i++)
2575 ret = tw.PostStatus(args.status.status, args.status.inReplyToId);
2576 if (string.IsNullOrEmpty(ret) ||
2577 ret.StartsWith("OK:") ||
2578 ret.StartsWith("Outputz:") ||
2579 ret.StartsWith("Warn:") ||
2580 ret == "Err:Status is a duplicate." ||
2581 args.status.status.StartsWith("D", StringComparison.OrdinalIgnoreCase) ||
2582 args.status.status.StartsWith("DM", StringComparison.OrdinalIgnoreCase) ||
2583 Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid)
2589 ret = this.pictureService[args.status.imageService].Upload(ref args.status.imagePath,
2590 ref args.status.status,
2591 args.status.inReplyToId);
2593 bw.ReportProgress(300);
2594 rslt.status = args.status;
2596 case MyCommon.WORKERTYPE.Retweet:
2597 bw.ReportProgress(200);
2598 for (int i = 0; i <= args.ids.Count - 1; i++)
2600 ret = tw.PostRetweet(args.ids[i], read);
2602 bw.ReportProgress(300);
2604 case MyCommon.WORKERTYPE.Follower:
2605 bw.ReportProgress(50, Properties.Resources.UpdateFollowersMenuItem1_ClickText1);
2606 ret = tw.GetFollowersApi();
2607 if (string.IsNullOrEmpty(ret))
2609 ret = tw.GetNoRetweetIdsApi();
2612 case MyCommon.WORKERTYPE.Configuration:
2613 ret = tw.ConfigurationApi();
2615 case MyCommon.WORKERTYPE.Favorites:
2616 bw.ReportProgress(50, MakeStatusMessage(args, false));
2617 ret = tw.GetFavoritesApi(read, args.type, args.page == -1);
2618 rslt.addCount = _statuses.DistributePosts();
2620 case MyCommon.WORKERTYPE.PublicSearch:
2621 bw.ReportProgress(50, MakeStatusMessage(args, false));
2622 if (string.IsNullOrEmpty(args.tName))
2624 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.PublicSearch))
2626 //if (!string.IsNullOrEmpty(tb.SearchWords)) ret = tw.GetPhoenixSearch(read, tb, false);
2627 if (!string.IsNullOrEmpty(tb.SearchWords)) ret = tw.GetSearch(read, tb, false);
2632 TabClass tb = _statuses.GetTabByName(args.tName);
2635 //ret = tw.GetPhoenixSearch(read, tb, false);
2636 ret = tw.GetSearch(read, tb, false);
2637 if (string.IsNullOrEmpty(ret) && args.page == -1)
2639 //ret = tw.GetPhoenixSearch(read, tb, true)
2640 ret = tw.GetSearch(read, tb, true);
2645 rslt.addCount = _statuses.DistributePosts();
2647 case MyCommon.WORKERTYPE.UserTimeline:
2648 bw.ReportProgress(50, MakeStatusMessage(args, false));
2650 if (SettingDialog.UseAdditionalCount) count = SettingDialog.UserTimelineCountApi;
2651 if (string.IsNullOrEmpty(args.tName))
2653 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.UserTimeline))
2655 if (!string.IsNullOrEmpty(tb.User)) ret = tw.GetUserTimelineApi(read, count, tb.User, tb, false);
2660 TabClass tb = _statuses.GetTabByName(args.tName);
2663 ret = tw.GetUserTimelineApi(read, count, tb.User, tb, args.page == -1);
2667 rslt.addCount = _statuses.DistributePosts();
2669 case MyCommon.WORKERTYPE.List:
2670 bw.ReportProgress(50, MakeStatusMessage(args, false));
2671 if (string.IsNullOrEmpty(args.tName))
2674 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.Lists))
2676 if (tb.ListInfo != null && tb.ListInfo.Id != 0) ret = tw.GetListStatus(read, tb, false, _initial);
2682 TabClass tb = _statuses.GetTabByName(args.tName);
2685 ret = tw.GetListStatus(read, tb, args.page == -1, _initial);
2689 rslt.addCount = _statuses.DistributePosts();
2691 case MyCommon.WORKERTYPE.Related:
2692 bw.ReportProgress(50, MakeStatusMessage(args, false));
2693 TabClass tab = _statuses.GetTabByName(args.tName);
2694 ret = tw.GetRelatedResult(read, tab);
2695 rslt.addCount = _statuses.DistributePosts();
2697 case MyCommon.WORKERTYPE.BlockIds:
2698 bw.ReportProgress(50, Properties.Resources.UpdateBlockUserText1);
2699 ret = tw.GetBlockUserIds();
2700 if (TabInformations.GetInstance().BlockIds.Count == 0)
2702 tw.GetBlockUserIds();
2707 if (bw.CancellationPending)
2714 if (args.type == MyCommon.WORKERTYPE.FavAdd)
2716 DateTime oneHour = DateTime.Now.Subtract(new TimeSpan(1, 0, 0));
2717 for (int i = _favTimestamps.Count - 1; i >= 0; i--)
2719 if (_favTimestamps[i].CompareTo(oneHour) < 0)
2721 _favTimestamps.RemoveAt(i);
2725 if (args.type == MyCommon.WORKERTYPE.Timeline && !_initial)
2729 DateTime tm = DateTime.Now;
2730 if (_tlTimestamps.ContainsKey(tm))
2731 _tlTimestamps[tm] += rslt.addCount;
2733 _tlTimestamps.Add(tm, rslt.addCount);
2735 DateTime oneHour = DateTime.Now.Subtract(new TimeSpan(1, 0, 0));
2736 List<DateTime> keys = new List<DateTime>();
2738 foreach (DateTime key in _tlTimestamps.Keys)
2740 if (key.CompareTo(oneHour) < 0)
2746 _tlCount += _tlTimestamps[key];
2749 foreach (DateTime key in keys)
2751 _tlTimestamps.Remove(key);
2758 bw.ReportProgress(100, MakeStatusMessage(args, true)); //ステータス書き換え、Notifyアイコンアニメーション開始
2761 rslt.type = args.type;
2762 rslt.tName = args.tName;
2763 if (args.type == MyCommon.WORKERTYPE.DirectMessegeRcv ||
2764 args.type == MyCommon.WORKERTYPE.DirectMessegeSnt ||
2765 args.type == MyCommon.WORKERTYPE.Reply ||
2766 args.type == MyCommon.WORKERTYPE.Timeline ||
2767 args.type == MyCommon.WORKERTYPE.Favorites)
2769 rslt.page = args.page - 1; //値が正しいか後でチェック。10ページ毎の継続確認
2775 private string MakeStatusMessage(GetWorkerArg AsyncArg, bool Finish)
2781 switch (AsyncArg.type)
2783 case MyCommon.WORKERTYPE.Timeline:
2784 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText5 + AsyncArg.page.ToString() + Properties.Resources.GetTimelineWorker_RunWorkerCompletedText6;
2786 case MyCommon.WORKERTYPE.Reply:
2787 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText4 + AsyncArg.page.ToString() + Properties.Resources.GetTimelineWorker_RunWorkerCompletedText6;
2789 case MyCommon.WORKERTYPE.DirectMessegeRcv:
2790 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText8 + AsyncArg.page.ToString() + Properties.Resources.GetTimelineWorker_RunWorkerCompletedText6;
2792 case MyCommon.WORKERTYPE.FavAdd:
2793 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText15 + AsyncArg.page.ToString() + "/" + AsyncArg.ids.Count.ToString() +
2794 Properties.Resources.GetTimelineWorker_RunWorkerCompletedText16 + (AsyncArg.page - AsyncArg.sIds.Count - 1).ToString();
2796 case MyCommon.WORKERTYPE.FavRemove:
2797 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText17 + AsyncArg.page.ToString() + "/" + AsyncArg.ids.Count.ToString() +
2798 Properties.Resources.GetTimelineWorker_RunWorkerCompletedText18 + (AsyncArg.page - AsyncArg.sIds.Count - 1).ToString();
2800 case MyCommon.WORKERTYPE.Favorites:
2801 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText19;
2803 case MyCommon.WORKERTYPE.PublicSearch:
2804 smsg = "Search refreshing...";
2806 case MyCommon.WORKERTYPE.List:
2807 smsg = "List refreshing...";
2809 case MyCommon.WORKERTYPE.Related:
2810 smsg = "Related refreshing...";
2812 case MyCommon.WORKERTYPE.UserTimeline:
2813 smsg = "UserTimeline refreshing...";
2820 switch (AsyncArg.type)
2822 case MyCommon.WORKERTYPE.Timeline:
2823 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText1;
2825 case MyCommon.WORKERTYPE.Reply:
2826 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText9;
2828 case MyCommon.WORKERTYPE.DirectMessegeRcv:
2829 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText11;
2831 case MyCommon.WORKERTYPE.DirectMessegeSnt:
2832 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText13;
2834 case MyCommon.WORKERTYPE.FavAdd:
2837 case MyCommon.WORKERTYPE.FavRemove:
2840 case MyCommon.WORKERTYPE.Favorites:
2841 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText20;
2843 case MyCommon.WORKERTYPE.Follower:
2844 smsg = Properties.Resources.UpdateFollowersMenuItem1_ClickText3;
2846 case MyCommon.WORKERTYPE.Configuration:
2849 case MyCommon.WORKERTYPE.PublicSearch:
2850 smsg = "Search refreshed";
2852 case MyCommon.WORKERTYPE.List:
2853 smsg = "List refreshed";
2855 case MyCommon.WORKERTYPE.Related:
2856 smsg = "Related refreshed";
2858 case MyCommon.WORKERTYPE.UserTimeline:
2859 smsg = "UserTimeline refreshed";
2861 case MyCommon.WORKERTYPE.BlockIds:
2862 smsg = Properties.Resources.UpdateBlockUserText3;
2869 private void GetTimelineWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
2871 if (MyCommon._endingFlag) return;
2872 if (e.ProgressPercentage > 100)
2875 if (e.ProgressPercentage == 200) //開始
2876 StatusLabel.Text = "Posting...";
2877 if (e.ProgressPercentage == 300) //終了
2878 StatusLabel.Text = Properties.Resources.PostWorker_RunWorkerCompletedText4;
2882 string smsg = (string)e.UserState;
2883 if (smsg.Length > 0) StatusLabel.Text = smsg;
2887 private void GetTimelineWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
2889 if (MyCommon._endingFlag || e.Cancelled) return; //キャンセル
2891 if (e.Error != null)
2893 _myStatusError = true;
2894 _waitTimeline = false;
2898 _waitPubSearch = false;
2899 _waitUserTimeline = false;
2901 throw new Exception("BackgroundWorker Exception", e.Error);
2904 GetWorkerResult rslt = (GetWorkerResult)e.Result;
2907 if (rslt.retMsg.Length > 0)
2909 _myStatusError = true;
2910 StatusLabel.Text = rslt.retMsg;
2913 if (rslt.type == MyCommon.WORKERTYPE.ErrorState) return;
2915 if (rslt.type == MyCommon.WORKERTYPE.FavRemove)
2917 this.RemovePostFromFavTab(rslt.sIds.ToArray());
2921 //bool busy = false;
2922 //foreach (BackgroundWorker bw in _bw)
2924 // if (bw != null && bw.IsBusy)
2930 //if (!busy) RefreshTimeline(); //background処理なければ、リスト反映
2931 if (rslt.type == MyCommon.WORKERTYPE.Timeline ||
2932 rslt.type == MyCommon.WORKERTYPE.Reply ||
2933 rslt.type == MyCommon.WORKERTYPE.List ||
2934 rslt.type == MyCommon.WORKERTYPE.PublicSearch ||
2935 rslt.type == MyCommon.WORKERTYPE.DirectMessegeRcv ||
2936 rslt.type == MyCommon.WORKERTYPE.DirectMessegeSnt ||
2937 rslt.type == MyCommon.WORKERTYPE.Favorites ||
2938 rslt.type == MyCommon.WORKERTYPE.Follower ||
2939 rslt.type == MyCommon.WORKERTYPE.FavAdd ||
2940 rslt.type == MyCommon.WORKERTYPE.FavRemove ||
2941 rslt.type == MyCommon.WORKERTYPE.Related ||
2942 rslt.type == MyCommon.WORKERTYPE.UserTimeline ||
2943 rslt.type == MyCommon.WORKERTYPE.BlockIds ||
2944 rslt.type == MyCommon.WORKERTYPE.Configuration)
2946 RefreshTimeline(false); //リスト反映
2951 case MyCommon.WORKERTYPE.Timeline:
2952 _waitTimeline = false;
2955 // //API使用時の取得調整は別途考える(カウント調整?)
2958 case MyCommon.WORKERTYPE.Reply:
2960 if (rslt.newDM && !_initial)
2962 GetTimeline(MyCommon.WORKERTYPE.DirectMessegeRcv, 1, 0, "");
2965 case MyCommon.WORKERTYPE.Favorites:
2968 case MyCommon.WORKERTYPE.DirectMessegeRcv:
2971 case MyCommon.WORKERTYPE.FavAdd:
2972 case MyCommon.WORKERTYPE.FavRemove:
2973 if (_curList != null && _curTab != null)
2975 _curList.BeginUpdate();
2976 if (rslt.type == MyCommon.WORKERTYPE.FavRemove && _statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.Favorites)
2982 for (int i = 0; i <= rslt.sIds.Count - 1; i++)
2984 if (_curTab.Text.Equals(rslt.tName))
2986 int idx = _statuses.Tabs[rslt.tName].IndexOf(rslt.sIds[i]);
2989 PostClass post = null;
2990 TabClass tb = _statuses.Tabs[rslt.tName];
2993 if (tb.TabType == MyCommon.TabUsageType.Lists || tb.TabType == MyCommon.TabUsageType.PublicSearch)
2995 post = tb.Posts[rslt.sIds[i]];
2999 post = _statuses[rslt.sIds[i]];
3001 ChangeCacheStyleRead(post.IsRead, idx, _curTab);
3003 if (idx == _curItemIndex) DispSelectedPost(true); //選択アイテム再表示
3008 _curList.EndUpdate();
3011 case MyCommon.WORKERTYPE.PostMessage:
3012 if (string.IsNullOrEmpty(rslt.retMsg) ||
3013 rslt.retMsg.StartsWith("Outputz") ||
3014 rslt.retMsg.StartsWith("OK:") ||
3015 rslt.retMsg == "Warn:Status is a duplicate.")
3017 _postTimestamps.Add(DateTime.Now);
3018 DateTime oneHour = DateTime.Now.Subtract(new TimeSpan(1, 0, 0));
3019 for (int i = _postTimestamps.Count - 1; i >= 0; i--)
3021 if (_postTimestamps[i].CompareTo(oneHour) < 0)
3023 _postTimestamps.RemoveAt(i);
3027 if (!HashMgr.IsPermanent && !string.IsNullOrEmpty(HashMgr.UseHash))
3029 HashMgr.ClearHashtag();
3030 this.HashStripSplitButton.Text = "#[-]";
3031 this.HashToggleMenuItem.Checked = false;
3032 this.HashToggleToolStripMenuItem.Checked = false;
3034 SetMainWindowTitle();
3042 retry = MessageBox.Show(string.Format("{0} ---> [ " + rslt.retMsg + " ]" + Environment.NewLine + "\"" + rslt.status.status + "\"" + Environment.NewLine + "{1}",
3043 Properties.Resources.StatusUpdateFailed1,
3044 Properties.Resources.StatusUpdateFailed2),
3045 "Failed to update status",
3046 MessageBoxButtons.RetryCancel,
3047 MessageBoxIcon.Question);
3051 retry = DialogResult.Abort;
3053 if (retry == DialogResult.Retry)
3055 GetWorkerArg args = new GetWorkerArg();
3058 args.type = MyCommon.WORKERTYPE.PostMessage;
3059 args.status = rslt.status;
3064 if (ToolStripFocusLockMenuItem.Checked)
3066 //連投モードのときだけEnterイベントが起きないので強制的に背景色を戻す
3067 StatusText_Enter(StatusText, new EventArgs());
3071 if (rslt.retMsg.Length == 0 && SettingDialog.PostAndGet)
3073 if (_isActiveUserstream)
3075 RefreshTimeline(true);
3079 GetTimeline(MyCommon.WORKERTYPE.Timeline, 1, 0, "");
3083 case MyCommon.WORKERTYPE.Retweet:
3084 if (rslt.retMsg.Length == 0)
3086 _postTimestamps.Add(DateTime.Now);
3087 DateTime oneHour = DateTime.Now.Subtract(new TimeSpan(1, 0, 0));
3088 for (int i = _postTimestamps.Count - 1; i >= 0; i--)
3090 if (_postTimestamps[i].CompareTo(oneHour) < 0)
3092 _postTimestamps.RemoveAt(i);
3095 if (!_isActiveUserstream && SettingDialog.PostAndGet) GetTimeline(MyCommon.WORKERTYPE.Timeline, 1, 0, "");
3098 case MyCommon.WORKERTYPE.Follower:
3099 //_waitFollower = false;
3100 this.PurgeListViewItemCache();
3101 if (_curList != null) _curList.Refresh();
3103 case MyCommon.WORKERTYPE.Configuration:
3104 //_waitFollower = false
3105 if (SettingDialog.TwitterConfiguration.PhotoSizeLimit != 0)
3107 pictureService["Twitter"].Configuration("MaxUploadFilesize", SettingDialog.TwitterConfiguration.PhotoSizeLimit);
3109 this.PurgeListViewItemCache();
3110 if (_curList != null) _curList.Refresh();
3112 case MyCommon.WORKERTYPE.PublicSearch:
3113 _waitPubSearch = false;
3115 case MyCommon.WORKERTYPE.UserTimeline:
3116 _waitUserTimeline = false;
3118 case MyCommon.WORKERTYPE.List:
3121 case MyCommon.WORKERTYPE.Related:
3122 TabClass tab = _statuses.GetTabByType(MyCommon.TabUsageType.Related);
3123 if (tab != null && tab.RelationTargetPost != null && tab.Contains(tab.RelationTargetPost.StatusId))
3125 foreach (TabPage tp in ListTab.TabPages)
3127 if (tp.Text == tab.TabName)
3129 ((DetailsListView)tp.Tag).SelectedIndices.Add(tab.IndexOf(tab.RelationTargetPost.StatusId));
3130 ((DetailsListView)tp.Tag).Items[tab.IndexOf(tab.RelationTargetPost.StatusId)].Focused = true;
3139 private void RemovePostFromFavTab(Int64[] ids)
3141 string favTabName = _statuses.GetTabByType(MyCommon.TabUsageType.Favorites).TabName;
3143 if (_curTab.Text.Equals(favTabName))
3145 if (_curList.FocusedItem != null)
3146 fidx = _curList.FocusedItem.Index;
3147 else if (_curList.TopItem != null)
3148 fidx = _curList.TopItem.Index;
3153 foreach (long i in ids)
3157 _statuses.RemoveFavPost(i);
3164 if (_curTab != null && _curTab.Text.Equals(favTabName))
3166 this.PurgeListViewItemCache();
3168 //_curItemIndex = -1;
3170 foreach (TabPage tp in ListTab.TabPages)
3172 if (tp.Text == favTabName)
3174 ((DetailsListView)tp.Tag).VirtualListSize = _statuses.Tabs[favTabName].AllCount;
3178 if (_curTab.Text.Equals(favTabName))
3182 _curList.SelectedIndices.Clear();
3184 while (_curList.SelectedIndices.Count > 0);
3186 if (_statuses.Tabs[favTabName].AllCount > 0)
3188 if (_statuses.Tabs[favTabName].AllCount - 1 > fidx && fidx > -1)
3190 _curList.SelectedIndices.Add(fidx);
3194 _curList.SelectedIndices.Add(_statuses.Tabs[favTabName].AllCount - 1);
3196 if (_curList.SelectedIndices.Count > 0)
3198 _curList.EnsureVisible(_curList.SelectedIndices[0]);
3199 _curList.FocusedItem = _curList.Items[_curList.SelectedIndices[0]];
3205 private static Dictionary<MyCommon.WORKERTYPE, DateTime> lastTime = new Dictionary<MyCommon.WORKERTYPE, DateTime>();
3207 private void GetTimeline(MyCommon.WORKERTYPE WkType, int fromPage, int toPage, string tabName)
3209 if (!this.IsNetworkAvailable()) return;
3212 GetWorkerArg args = new GetWorkerArg();
3213 args.page = fromPage;
3214 args.endPage = toPage;
3216 args.tName = tabName;
3218 if (!lastTime.ContainsKey(WkType)) lastTime.Add(WkType, new DateTime());
3219 double period = DateTime.Now.Subtract(lastTime[WkType]).TotalSeconds;
3220 if (period > 1 || period < -1)
3222 lastTime[WkType] = DateTime.Now;
3226 //Timeline取得モードの場合はReplyも同時に取得
3227 //if (!SettingDialog.UseAPI &&
3229 // WkType == MyCommon.WORKERTYPE.Timeline &&
3230 // SettingDialog.CheckReply)
3232 // //TimerReply.Enabled = false;
3233 // _mentionCounter = SettingDialog.ReplyPeriodInt;
3234 // GetWorkerArg _args = new GetWorkerArg();
3235 // _args.page = fromPage;
3236 // _args.endPage = toPage;
3237 // _args.type = MyCommon.WORKERTYPE.Reply;
3242 private void NotifyIcon1_MouseClick(object sender, MouseEventArgs e)
3244 if (e.Button == MouseButtons.Left)
3246 this.Visible = true;
3247 if (this.WindowState == FormWindowState.Minimized)
3249 this.WindowState = _formWindowState;
3252 this.BringToFront();
3256 private void MyList_MouseDoubleClick(object sender, MouseEventArgs e)
3258 switch (SettingDialog.ListDoubleClickAction)
3261 MakeReplyOrDirectStatus();
3264 FavoriteChange(true);
3267 if (_curPost != null)
3268 ShowUserStatus(_curPost.ScreenName, false);
3274 ShowRelatedStatusesMenuItem_Click(null, null);
3277 MoveToHomeToolStripMenuItem_Click(null, null);
3280 StatusOpenMenuItem_Click(null, null);
3288 private void FavAddToolStripMenuItem_Click(object sender, EventArgs e)
3290 FavoriteChange(true);
3293 private void FavRemoveToolStripMenuItem_Click(object sender, EventArgs e)
3295 FavoriteChange(false);
3299 private void FavoriteRetweetMenuItem_Click(object sender, EventArgs e)
3301 FavoritesRetweetOriginal();
3304 private void FavoriteRetweetUnofficialMenuItem_Click(object sender, EventArgs e)
3306 FavoritesRetweetUnofficial();
3309 private void FavoriteChange(bool FavAdd , bool multiFavoriteChangeDialogEnable = true)
3311 //trueでFavAdd,falseでFavRemove
3312 if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage || _curList.SelectedIndices.Count == 0
3313 || !this.ExistCurrentPost) return;
3316 if (_curList.SelectedIndices.Count > 250 && FavAdd)
3318 MessageBox.Show(Properties.Resources.FavoriteLimitCountText);
3319 _DoFavRetweetFlags = false;
3322 else if (multiFavoriteChangeDialogEnable && _curList.SelectedIndices.Count > 1)
3326 string QuestionText = Properties.Resources.FavAddToolStripMenuItem_ClickText1;
3327 if (_DoFavRetweetFlags) QuestionText = Properties.Resources.FavoriteRetweetQuestionText3;
3328 if (MessageBox.Show(QuestionText, Properties.Resources.FavAddToolStripMenuItem_ClickText2,
3329 MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
3331 _DoFavRetweetFlags = false;
3337 if (MessageBox.Show(Properties.Resources.FavRemoveToolStripMenuItem_ClickText1, Properties.Resources.FavRemoveToolStripMenuItem_ClickText2,
3338 MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
3345 GetWorkerArg args = new GetWorkerArg();
3346 args.ids = new List<long>();
3347 args.sIds = new List<long>();
3348 args.tName = _curTab.Text;
3351 args.type = MyCommon.WORKERTYPE.FavAdd;
3355 args.type = MyCommon.WORKERTYPE.FavRemove;
3357 foreach (int idx in _curList.SelectedIndices)
3359 PostClass post = GetCurTabPost(idx);
3362 if (!post.IsFav) args.ids.Add(post.StatusId);
3366 if (post.IsFav) args.ids.Add(post.StatusId);
3369 if (args.ids.Count == 0)
3372 StatusLabel.Text = Properties.Resources.FavAddToolStripMenuItem_ClickText4;
3374 StatusLabel.Text = Properties.Resources.FavRemoveToolStripMenuItem_ClickText4;
3382 private PostClass GetCurTabPost(int Index)
3384 if (_postCache != null && Index >= _itemCacheIndex && Index < _itemCacheIndex + _postCache.Length)
3385 return _postCache[Index - _itemCacheIndex];
3387 return _statuses[_curTab.Text, Index];
3391 private void MoveToHomeToolStripMenuItem_Click(object sender, EventArgs e)
3393 if (_curList.SelectedIndices.Count > 0)
3394 OpenUriAsync(MyCommon.TwitterUrl + GetCurTabPost(_curList.SelectedIndices[0]).ScreenName);
3395 else if (_curList.SelectedIndices.Count == 0)
3396 OpenUriAsync(MyCommon.TwitterUrl);
3399 private void MoveToFavToolStripMenuItem_Click(object sender, EventArgs e)
3401 if (_curList.SelectedIndices.Count > 0)
3402 OpenUriAsync(MyCommon.TwitterUrl + "#!/" + GetCurTabPost(_curList.SelectedIndices[0]).ScreenName + "/favorites");
3405 private void Tween_ClientSizeChanged(object sender, EventArgs e)
3407 if ((!_initialLayout) && this.Visible)
3409 if (this.WindowState == FormWindowState.Normal)
3411 _mySize = this.ClientSize;
3412 _mySpDis = this.SplitContainer1.SplitterDistance;
3413 _mySpDis3 = this.SplitContainer3.SplitterDistance;
3414 if (StatusText.Multiline) _mySpDis2 = this.StatusText.Height;
3415 _modifySettingLocal = true;
3420 private void MyList_ColumnClick(object sender, ColumnClickEventArgs e)
3422 if (SettingDialog.SortOrderLock) return;
3423 IdComparerClass.ComparerMode mode = IdComparerClass.ComparerMode.Id;
3426 mode = IdComparerClass.ComparerMode.Id;
3434 case 6: //0:アイコン,5:未読マーク,6:プロテクト・フィルターマーク
3438 mode = IdComparerClass.ComparerMode.Nickname;
3441 mode = IdComparerClass.ComparerMode.Data;
3444 mode = IdComparerClass.ComparerMode.Id;
3447 mode = IdComparerClass.ComparerMode.Name;
3450 mode = IdComparerClass.ComparerMode.Source;
3454 _statuses.ToggleSortOrder(mode);
3457 DetailsListView list = (DetailsListView)sender;
3460 list.Columns[0].Text = ColumnOrgText[0];
3461 list.Columns[1].Text = ColumnText[2];
3465 for (int i = 0; i <= 7; i++)
3467 list.Columns[i].Text = ColumnOrgText[i];
3469 list.Columns[e.Column].Text = ColumnText[e.Column];
3472 this.PurgeListViewItemCache();
3474 if (_statuses.Tabs[_curTab.Text].AllCount > 0 && _curPost != null)
3476 int idx = _statuses.Tabs[_curTab.Text].IndexOf(_curPost.StatusId);
3479 SelectListItem(_curList, idx);
3480 _curList.EnsureVisible(idx);
3484 _modifySettingCommon = true;
3487 private void Tween_LocationChanged(object sender, EventArgs e)
3489 if (this.WindowState == FormWindowState.Normal && !_initialLayout)
3491 _myLoc = this.DesktopLocation;
3492 _modifySettingLocal = true;
3496 private void ContextMenuOperate_Opening(object sender, CancelEventArgs e)
3498 if (ListTab.SelectedTab == null) return;
3499 if (_statuses == null || _statuses.Tabs == null || !_statuses.Tabs.ContainsKey(ListTab.SelectedTab.Text)) return;
3500 if (!this.ExistCurrentPost)
3502 ReplyStripMenuItem.Enabled = false;
3503 ReplyAllStripMenuItem.Enabled = false;
3504 DMStripMenuItem.Enabled = false;
3505 ShowProfileMenuItem.Enabled = false;
3506 ShowUserTimelineContextMenuItem.Enabled = false;
3507 ListManageUserContextToolStripMenuItem2.Enabled = false;
3508 MoveToFavToolStripMenuItem.Enabled = false;
3509 TabMenuItem.Enabled = false;
3510 IDRuleMenuItem.Enabled = false;
3511 ReadedStripMenuItem.Enabled = false;
3512 UnreadStripMenuItem.Enabled = false;
3516 ShowProfileMenuItem.Enabled = true;
3517 ListManageUserContextToolStripMenuItem2.Enabled = true;
3518 ReplyStripMenuItem.Enabled = true;
3519 ReplyAllStripMenuItem.Enabled = true;
3520 DMStripMenuItem.Enabled = true;
3521 ShowUserTimelineContextMenuItem.Enabled = true;
3522 MoveToFavToolStripMenuItem.Enabled = true;
3523 TabMenuItem.Enabled = true;
3524 IDRuleMenuItem.Enabled = true;
3525 ReadedStripMenuItem.Enabled = true;
3526 UnreadStripMenuItem.Enabled = true;
3528 DeleteStripMenuItem.Text = Properties.Resources.DeleteMenuText1;
3529 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.DirectMessage || !this.ExistCurrentPost || _curPost.IsDm)
3531 FavAddToolStripMenuItem.Enabled = false;
3532 FavRemoveToolStripMenuItem.Enabled = false;
3533 StatusOpenMenuItem.Enabled = false;
3534 FavorareMenuItem.Enabled = false;
3535 ShowRelatedStatusesMenuItem.Enabled = false;
3537 ReTweetStripMenuItem.Enabled = false;
3538 ReTweetOriginalStripMenuItem.Enabled = false;
3539 QuoteStripMenuItem.Enabled = false;
3540 FavoriteRetweetContextMenu.Enabled = false;
3541 FavoriteRetweetUnofficialContextMenu.Enabled = false;
3542 if (this.ExistCurrentPost && _curPost.IsDm)
3543 DeleteStripMenuItem.Enabled = true;
3545 DeleteStripMenuItem.Enabled = false;
3549 FavAddToolStripMenuItem.Enabled = true;
3550 FavRemoveToolStripMenuItem.Enabled = true;
3551 StatusOpenMenuItem.Enabled = true;
3552 FavorareMenuItem.Enabled = true;
3553 ShowRelatedStatusesMenuItem.Enabled = true; //PublicSearchの時問題出るかも
3557 ReTweetOriginalStripMenuItem.Enabled = false;
3558 FavoriteRetweetContextMenu.Enabled = false;
3559 if (string.IsNullOrEmpty(_curPost.RetweetedBy))
3561 DeleteStripMenuItem.Text = Properties.Resources.DeleteMenuText1;
3565 DeleteStripMenuItem.Text = Properties.Resources.DeleteMenuText2;
3567 DeleteStripMenuItem.Enabled = true;
3571 if (string.IsNullOrEmpty(_curPost.RetweetedBy))
3573 DeleteStripMenuItem.Text = Properties.Resources.DeleteMenuText1;
3577 DeleteStripMenuItem.Text = Properties.Resources.DeleteMenuText2;
3579 DeleteStripMenuItem.Enabled = false;
3580 if (_curPost.IsProtect)
3582 ReTweetOriginalStripMenuItem.Enabled = false;
3583 ReTweetStripMenuItem.Enabled = false;
3584 QuoteStripMenuItem.Enabled = false;
3585 FavoriteRetweetContextMenu.Enabled = false;
3586 FavoriteRetweetUnofficialContextMenu.Enabled = false;
3590 ReTweetOriginalStripMenuItem.Enabled = true;
3591 ReTweetStripMenuItem.Enabled = true;
3592 QuoteStripMenuItem.Enabled = true;
3593 FavoriteRetweetContextMenu.Enabled = true;
3594 FavoriteRetweetUnofficialContextMenu.Enabled = true;
3598 //if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType != MyCommon.TabUsageType.Favorites)
3600 // RefreshMoreStripMenuItem.Enabled = true;
3604 // RefreshMoreStripMenuItem.Enabled = false;
3606 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.PublicSearch
3607 || !this.ExistCurrentPost
3608 || !(_curPost.InReplyToStatusId > 0))
3610 RepliedStatusOpenMenuItem.Enabled = false;
3614 RepliedStatusOpenMenuItem.Enabled = true;
3616 if (!this.ExistCurrentPost || string.IsNullOrEmpty(_curPost.RetweetedBy))
3618 MoveToRTHomeMenuItem.Enabled = false;
3622 MoveToRTHomeMenuItem.Enabled = true;
3626 private void ReplyStripMenuItem_Click(object sender, EventArgs e)
3628 MakeReplyOrDirectStatus(false, true);
3631 private void DMStripMenuItem_Click(object sender, EventArgs e)
3633 MakeReplyOrDirectStatus(false, false);
3636 private void doStatusDelete()
3638 if (_curTab == null || _curList == null) return;
3639 if (_statuses.Tabs[_curTab.Text].TabType != MyCommon.TabUsageType.DirectMessage)
3641 bool myPost = false;
3642 foreach (int idx in _curList.SelectedIndices)
3644 if (GetCurTabPost(idx).IsMe ||
3645 GetCurTabPost(idx).RetweetedBy.ToLower() == tw.Username.ToLower())
3651 if (!myPost) return;
3655 if (_curList.SelectedIndices.Count == 0)
3659 string tmp = string.Format(Properties.Resources.DeleteStripMenuItem_ClickText1, Environment.NewLine);
3661 if (MessageBox.Show(tmp, Properties.Resources.DeleteStripMenuItem_ClickText2,
3662 MessageBoxButtons.OKCancel,
3663 MessageBoxIcon.Question) == DialogResult.Cancel) return;
3666 if (_curList.FocusedItem != null)
3667 fidx = _curList.FocusedItem.Index;
3668 else if (_curList.TopItem != null)
3669 fidx = _curList.TopItem.Index;
3675 this.Cursor = Cursors.WaitCursor;
3678 foreach (long Id in _statuses.GetId(_curTab.Text, _curList.SelectedIndices))
3681 if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage)
3683 rtn = tw.RemoveDirectMessage(Id, _statuses[Id]);
3687 if (_statuses[Id].IsMe || _statuses[Id].RetweetedBy.ToLower() == tw.Username.ToLower())
3688 rtn = tw.RemoveStatus(Id);
3699 _statuses.RemovePost(Id);
3704 StatusLabel.Text = Properties.Resources.DeleteStripMenuItem_ClickText3; //失敗
3706 StatusLabel.Text = Properties.Resources.DeleteStripMenuItem_ClickText4; //成功
3708 this.PurgeListViewItemCache();
3711 foreach (TabPage tb in ListTab.TabPages)
3713 ((DetailsListView)tb.Tag).VirtualListSize = _statuses.Tabs[tb.Text].AllCount;
3714 if (_curTab.Equals(tb))
3718 _curList.SelectedIndices.Clear();
3720 while (_curList.SelectedIndices.Count > 0);
3722 if (_statuses.Tabs[tb.Text].AllCount > 0)
3724 if (_statuses.Tabs[tb.Text].AllCount - 1 > fidx && fidx > -1)
3725 _curList.SelectedIndices.Add(fidx);
3727 _curList.SelectedIndices.Add(_statuses.Tabs[tb.Text].AllCount - 1);
3729 if (_curList.SelectedIndices.Count > 0)
3731 _curList.EnsureVisible(_curList.SelectedIndices[0]);
3732 _curList.FocusedItem = _curList.Items[_curList.SelectedIndices[0]];
3736 if (_statuses.Tabs[tb.Text].UnreadCount == 0)
3738 if (SettingDialog.TabIconDisp)
3740 if (tb.ImageIndex == 0) tb.ImageIndex = -1; //タブアイコン
3744 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
3748 this.Cursor = Cursors.Default;
3752 private void DeleteStripMenuItem_Click(object sender, EventArgs e)
3757 private void ReadedStripMenuItem_Click(object sender, EventArgs e)
3759 _curList.BeginUpdate();
3760 if (SettingDialog.UnreadManage)
3762 foreach (int idx in _curList.SelectedIndices)
3764 _statuses.SetReadAllTab(true, _curTab.Text, idx);
3767 foreach (int idx in _curList.SelectedIndices)
3769 ChangeCacheStyleRead(true, idx, _curTab);
3772 _curList.EndUpdate();
3773 foreach (TabPage tb in ListTab.TabPages)
3775 if (_statuses.Tabs[tb.Text].UnreadCount == 0)
3777 if (SettingDialog.TabIconDisp)
3779 if (tb.ImageIndex == 0) tb.ImageIndex = -1; //タブアイコン
3783 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
3786 private void UnreadStripMenuItem_Click(object sender, EventArgs e)
3788 _curList.BeginUpdate();
3789 if (SettingDialog.UnreadManage)
3791 foreach (int idx in _curList.SelectedIndices)
3793 _statuses.SetReadAllTab(false, _curTab.Text, idx);
3796 foreach (int idx in _curList.SelectedIndices)
3798 ChangeCacheStyleRead(false, idx, _curTab);
3801 _curList.EndUpdate();
3802 foreach (TabPage tb in ListTab.TabPages)
3804 if (_statuses.Tabs[tb.Text].UnreadCount > 0)
3806 if (SettingDialog.TabIconDisp)
3808 if (tb.ImageIndex == -1) tb.ImageIndex = 0; //タブアイコン
3812 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
3815 private void RefreshStripMenuItem_Click(object sender, EventArgs e)
3820 private void DoRefresh()
3822 if (_curTab != null)
3824 switch (_statuses.Tabs[_curTab.Text].TabType)
3826 case MyCommon.TabUsageType.Mentions:
3827 GetTimeline(MyCommon.WORKERTYPE.Reply, 1, 0, "");
3829 case MyCommon.TabUsageType.DirectMessage:
3830 GetTimeline(MyCommon.WORKERTYPE.DirectMessegeRcv, 1, 0, "");
3832 case MyCommon.TabUsageType.Favorites:
3833 GetTimeline(MyCommon.WORKERTYPE.Favorites, 1, 0, "");
3835 //case MyCommon.TabUsageType.Profile:
3837 case MyCommon.TabUsageType.PublicSearch:
3839 TabClass tb = _statuses.Tabs[_curTab.Text];
3840 if (string.IsNullOrEmpty(tb.SearchWords)) return;
3841 GetTimeline(MyCommon.WORKERTYPE.PublicSearch, 1, 0, _curTab.Text);
3843 case MyCommon.TabUsageType.UserTimeline:
3844 GetTimeline(MyCommon.WORKERTYPE.UserTimeline, 1, 0, _curTab.Text);
3846 case MyCommon.TabUsageType.Lists:
3848 TabClass tab = _statuses.Tabs[_curTab.Text];
3849 if (tab.ListInfo == null || tab.ListInfo.Id == 0) return;
3850 GetTimeline(MyCommon.WORKERTYPE.List, 1, 0, _curTab.Text);
3853 GetTimeline(MyCommon.WORKERTYPE.Timeline, 1, 0, "");
3859 GetTimeline(MyCommon.WORKERTYPE.Timeline, 1, 0, "");
3863 private void DoRefreshMore()
3866 if (_curTab != null)
3868 switch (_statuses.Tabs[_curTab.Text].TabType)
3870 case MyCommon.TabUsageType.Mentions:
3871 GetTimeline(MyCommon.WORKERTYPE.Reply, -1, 0, "");
3873 case MyCommon.TabUsageType.DirectMessage:
3874 GetTimeline(MyCommon.WORKERTYPE.DirectMessegeRcv, -1, 0, "");
3876 case MyCommon.TabUsageType.Favorites:
3877 GetTimeline(MyCommon.WORKERTYPE.Favorites, -1, 0, "");
3879 case MyCommon.TabUsageType.Profile:
3882 case MyCommon.TabUsageType.PublicSearch:
3884 TabClass tb = _statuses.Tabs[_curTab.Text];
3885 if (string.IsNullOrEmpty(tb.SearchWords)) return;
3886 GetTimeline(MyCommon.WORKERTYPE.PublicSearch, -1, 0, _curTab.Text);
3888 case MyCommon.TabUsageType.UserTimeline:
3889 GetTimeline(MyCommon.WORKERTYPE.UserTimeline, -1, 0, _curTab.Text);
3891 case MyCommon.TabUsageType.Lists:
3893 TabClass tab = _statuses.Tabs[_curTab.Text];
3894 if (tab.ListInfo == null || tab.ListInfo.Id == 0) return;
3895 GetTimeline(MyCommon.WORKERTYPE.List, -1, 0, _curTab.Text);
3898 GetTimeline(MyCommon.WORKERTYPE.Timeline, -1, 0, "");
3904 GetTimeline(MyCommon.WORKERTYPE.Timeline, -1, 0, "");
3908 private void SettingStripMenuItem_Click(object sender, EventArgs e)
3910 DialogResult result;
3911 string uid = tw.Username.ToLower();
3915 result = SettingDialog.ShowDialog(this);
3922 if (result == DialogResult.OK)
3926 tw.TinyUrlResolve = SettingDialog.TinyUrlResolve;
3927 tw.RestrictFavCheck = SettingDialog.RestrictFavCheck;
3928 tw.ReadOwnPost = SettingDialog.ReadOwnPost;
3929 tw.UseSsl = SettingDialog.UseSsl;
3930 ShortUrl.IsResolve = SettingDialog.TinyUrlResolve;
3931 ShortUrl.IsForceResolve = SettingDialog.ShortUrlForceResolve;
3932 ShortUrl.BitlyId = SettingDialog.BitlyUser;
3933 ShortUrl.BitlyKey = SettingDialog.BitlyPwd;
3934 HttpTwitter.TwitterUrl = _cfgCommon.TwitterUrl;
3935 HttpTwitter.TwitterSearchUrl = _cfgCommon.TwitterSearchUrl;
3937 HttpConnection.InitializeConnection(SettingDialog.DefaultTimeOut,
3938 SettingDialog.SelectedProxyType,
3939 SettingDialog.ProxyAddress,
3940 SettingDialog.ProxyPort,
3941 SettingDialog.ProxyUser,
3942 SettingDialog.ProxyPassword);
3943 this.CreatePictureServices();
3945 this.SplitContainer4.Panel2.Controls.RemoveAt(0);
3946 this.ab = new AdsBrowser();
3947 this.SplitContainer4.Panel2.Controls.Add(ab);
3951 if (SettingDialog.TabIconDisp)
3953 ListTab.DrawItem -= ListTab_DrawItem;
3954 ListTab.DrawMode = TabDrawMode.Normal;
3955 ListTab.ImageList = this.TabImage;
3959 ListTab.DrawItem -= ListTab_DrawItem;
3960 ListTab.DrawItem += ListTab_DrawItem;
3961 ListTab.DrawMode = TabDrawMode.OwnerDrawFixed;
3962 ListTab.ImageList = null;
3965 catch (Exception ex)
3967 ex.Data["Instance"] = "ListTab(TabIconDisp)";
3968 ex.Data["IsTerminatePermission"] = false;
3974 if (!SettingDialog.UnreadManage)
3976 ReadedStripMenuItem.Enabled = false;
3977 UnreadStripMenuItem.Enabled = false;
3978 if (SettingDialog.TabIconDisp)
3980 foreach (TabPage myTab in ListTab.TabPages)
3982 myTab.ImageIndex = -1;
3988 ReadedStripMenuItem.Enabled = true;
3989 UnreadStripMenuItem.Enabled = true;
3992 catch (Exception ex)
3994 ex.Data["Instance"] = "ListTab(UnreadManage)";
3995 ex.Data["IsTerminatePermission"] = false;
4001 foreach (TabPage mytab in ListTab.TabPages)
4003 DetailsListView lst = (DetailsListView)mytab.Tag;
4004 lst.GridLines = SettingDialog.ShowGrid;
4007 catch (Exception ex)
4009 ex.Data["Instance"] = "ListTab(ShowGrid)";
4010 ex.Data["IsTerminatePermission"] = false;
4017 PlaySoundMenuItem.Checked = SettingDialog.PlaySound;
4018 this.PlaySoundFileMenuItem.Checked = SettingDialog.PlaySound;
4019 _fntUnread = SettingDialog.FontUnread;
4020 _clUnread = SettingDialog.ColorUnread;
4021 _fntReaded = SettingDialog.FontReaded;
4022 _clReaded = SettingDialog.ColorReaded;
4023 _clFav = SettingDialog.ColorFav;
4024 _clOWL = SettingDialog.ColorOWL;
4025 _clRetweet = SettingDialog.ColorRetweet;
4026 _fntDetail = SettingDialog.FontDetail;
4027 _clDetail = SettingDialog.ColorDetail;
4028 _clDetailLink = SettingDialog.ColorDetailLink;
4029 _clDetailBackcolor = SettingDialog.ColorDetailBackcolor;
4030 _clSelf = SettingDialog.ColorSelf;
4031 _clAtSelf = SettingDialog.ColorAtSelf;
4032 _clTarget = SettingDialog.ColorTarget;
4033 _clAtTarget = SettingDialog.ColorAtTarget;
4034 _clAtFromTarget = SettingDialog.ColorAtFromTarget;
4035 _clAtTo = SettingDialog.ColorAtTo;
4036 _clListBackcolor = SettingDialog.ColorListBackcolor;
4037 _clInputBackcolor = SettingDialog.ColorInputBackcolor;
4038 _clInputFont = SettingDialog.ColorInputFont;
4039 _fntInputFont = SettingDialog.FontInputFont;
4042 if (StatusText.Focused) StatusText.BackColor = _clInputBackcolor;
4043 StatusText.Font = _fntInputFont;
4044 StatusText.ForeColor = _clInputFont;
4046 catch (Exception ex)
4048 MessageBox.Show(ex.Message);
4051 _brsForeColorUnread.Dispose();
4052 _brsForeColorReaded.Dispose();
4053 _brsForeColorFav.Dispose();
4054 _brsForeColorOWL.Dispose();
4055 _brsForeColorRetweet.Dispose();
4056 _brsForeColorUnread = new SolidBrush(_clUnread);
4057 _brsForeColorReaded = new SolidBrush(_clReaded);
4058 _brsForeColorFav = new SolidBrush(_clFav);
4059 _brsForeColorOWL = new SolidBrush(_clOWL);
4060 _brsForeColorRetweet = new SolidBrush(_clRetweet);
4061 _brsBackColorMine.Dispose();
4062 _brsBackColorAt.Dispose();
4063 _brsBackColorYou.Dispose();
4064 _brsBackColorAtYou.Dispose();
4065 _brsBackColorAtFromTarget.Dispose();
4066 _brsBackColorAtTo.Dispose();
4067 _brsBackColorNone.Dispose();
4068 _brsBackColorMine = new SolidBrush(_clSelf);
4069 _brsBackColorAt = new SolidBrush(_clAtSelf);
4070 _brsBackColorYou = new SolidBrush(_clTarget);
4071 _brsBackColorAtYou = new SolidBrush(_clAtTarget);
4072 _brsBackColorAtFromTarget = new SolidBrush(_clAtFromTarget);
4073 _brsBackColorAtTo = new SolidBrush(_clAtTo);
4074 _brsBackColorNone = new SolidBrush(_clListBackcolor);
4077 if (SettingDialog.IsMonospace)
4079 detailHtmlFormatHeader = detailHtmlFormatMono1;
4080 detailHtmlFormatFooter = detailHtmlFormatMono7;
4084 detailHtmlFormatHeader = detailHtmlFormat1;
4085 detailHtmlFormatFooter = detailHtmlFormat7;
4087 detailHtmlFormatHeader += _fntDetail.Name + detailHtmlFormat2 + _fntDetail.Size.ToString() + detailHtmlFormat3 + _clDetail.R.ToString() + "," + _clDetail.G.ToString() + "," + _clDetail.B.ToString() + detailHtmlFormat4 + _clDetailLink.R.ToString() + "," + _clDetailLink.G.ToString() + "," + _clDetailLink.B.ToString() + detailHtmlFormat5 + _clDetailBackcolor.R.ToString() + "," + _clDetailBackcolor.G.ToString() + "," + _clDetailBackcolor.B.ToString();
4088 if (SettingDialog.IsMonospace)
4090 detailHtmlFormatHeader += detailHtmlFormatMono6;
4094 detailHtmlFormatHeader += detailHtmlFormat6;
4097 catch (Exception ex)
4099 ex.Data["Instance"] = "Font";
4100 ex.Data["IsTerminatePermission"] = false;
4105 _statuses.SetUnreadManage(SettingDialog.UnreadManage);
4107 catch (Exception ex)
4109 ex.Data["Instance"] = "_statuses";
4110 ex.Data["IsTerminatePermission"] = false;
4116 foreach (TabPage tb in ListTab.TabPages)
4118 if (SettingDialog.TabIconDisp)
4120 if (_statuses.Tabs[tb.Text].UnreadCount == 0)
4125 if (tb.Tag != null && tb.Controls.Count > 0)
4127 ((DetailsListView)tb.Tag).Font = _fntReaded;
4128 ((DetailsListView)tb.Tag).BackColor = _clListBackcolor;
4132 catch (Exception ex)
4134 ex.Data["Instance"] = "ListTab(TabIconDisp no2)";
4135 ex.Data["IsTerminatePermission"] = false;
4138 SetMainWindowTitle();
4139 SetNotifyIconText();
4141 this.PurgeListViewItemCache();
4142 if (_curList != null) _curList.Refresh();
4145 Outputz.Key = SettingDialog.OutputzKey;
4146 Outputz.Enabled = SettingDialog.OutputzEnabled;
4147 switch (SettingDialog.OutputzUrlmode)
4149 case MyCommon.OutputzUrlmode.twittercom:
4150 Outputz.OutUrl = "http://twitter.com/";
4152 case MyCommon.OutputzUrlmode.twittercomWithUsername:
4153 Outputz.OutUrl = "http://twitter.com/" + tw.Username;
4157 _hookGlobalHotkey.UnregisterAllOriginalHotkey();
4158 if (SettingDialog.HotkeyEnabled)
4160 ///グローバルホットキーの登録。設定で変更可能にするかも
4161 HookGlobalHotkey.ModKeys modKey = HookGlobalHotkey.ModKeys.None;
4162 if ((SettingDialog.HotkeyMod & Keys.Alt) == Keys.Alt) modKey = modKey | HookGlobalHotkey.ModKeys.Alt;
4163 if ((SettingDialog.HotkeyMod & Keys.Control) == Keys.Control) modKey = modKey | HookGlobalHotkey.ModKeys.Ctrl;
4164 if ((SettingDialog.HotkeyMod & Keys.Shift) == Keys.Shift) modKey = modKey | HookGlobalHotkey.ModKeys.Shift;
4165 if ((SettingDialog.HotkeyMod & Keys.LWin) == Keys.LWin) modKey = modKey | HookGlobalHotkey.ModKeys.Win;
4167 _hookGlobalHotkey.RegisterOriginalHotkey(SettingDialog.HotkeyKey, SettingDialog.HotkeyValue, modKey);
4170 if (uid != tw.Username) this.doGetFollowersMenu();
4172 SetImageServiceCombo();
4173 if (SettingDialog.IsNotifyUseGrowl) gh.RegisterGrowl();
4176 StatusText_TextChanged(null, null);
4184 Twitter.AccountState = MyCommon.ACCOUNT_STATE.Valid;
4186 this.TopMost = SettingDialog.AlwaysTop;
4187 SaveConfigsAll(false);
4193 private void SetTabAlignment()
4195 ListTab.Alignment = (SettingDialog.ViewTabBottom ? TabAlignment.Bottom : TabAlignment.Top);
4198 private void PostBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
4200 if (e.Url.AbsoluteUri != "about:blank")
4203 OpenUriAsync(e.Url.OriginalString);
4207 private void PostBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
4209 if (e.Url.Scheme == "data")
4211 StatusLabelUrl.Text = PostBrowser.StatusText.Replace("&", "&&");
4213 else if (e.Url.AbsoluteUri != "about:blank")
4217 if (e.Url.AbsoluteUri.StartsWith("http://twitter.com/search?q=%23") ||
4218 e.Url.AbsoluteUri.StartsWith("https://twitter.com/search?q=%23"))
4221 string urlStr = Uri.UnescapeDataString(e.Url.AbsoluteUri);
4222 int i = urlStr.IndexOf('#');
4223 if (i == -1) return;
4225 string hash = urlStr.Substring(i);
4226 HashSupl.AddItem(hash);
4227 HashMgr.AddHashToHistory(hash.Trim(), false);
4228 AddNewTabForSearch(hash);
4233 Match m = Regex.Match(e.Url.AbsoluteUri, "^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)$");
4234 if (m.Success && IsTwitterId(m.Result("${ScreenName}")))
4236 // Ctrlを押しながらリンクをクリックした場合は設定と逆の動作をする
4237 if (SettingDialog.OpenUserTimeline)
4239 if (MyCommon.IsKeyDown(Keys.Control))
4240 OpenUriAsync(e.Url.OriginalString);
4242 this.AddNewTabForUserTimeline(m.Result("${ScreenName}"));
4246 if (MyCommon.IsKeyDown(Keys.Control))
4247 this.AddNewTabForUserTimeline(m.Result("${ScreenName}"));
4249 OpenUriAsync(e.Url.OriginalString);
4254 OpenUriAsync(e.Url.OriginalString);
4260 public void AddNewTabForSearch(string searchWord)
4262 //同一検索条件のタブが既に存在すれば、そのタブアクティブにして終了
4263 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.PublicSearch))
4265 if (tb.SearchWords == searchWord && string.IsNullOrEmpty(tb.SearchLang))
4267 foreach (TabPage tp in ListTab.TabPages)
4269 if (tb.TabName == tp.Text)
4271 ListTab.SelectedTab = tp;
4278 string tabName = searchWord;
4279 for (int i = 0; i <= 100; i++)
4281 if (_statuses.ContainsTab(tabName))
4287 _statuses.AddTab(tabName, MyCommon.TabUsageType.PublicSearch, null);
4288 AddNewTab(tabName, false, MyCommon.TabUsageType.PublicSearch);
4290 ListTab.SelectedIndex = ListTab.TabPages.Count - 1;
4292 ComboBox cmb = (ComboBox)ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"];
4293 cmb.Items.Add(searchWord);
4294 cmb.Text = searchWord;
4297 this.SearchButton_Click(ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"], null);
4300 private void ShowUserTimeline()
4302 if (!this.ExistCurrentPost) return;
4303 AddNewTabForUserTimeline(_curPost.ScreenName);
4306 private void SearchComboBox_KeyDown(object sender, KeyEventArgs e)
4308 if (e.KeyCode == Keys.Escape)
4310 TabPage relTp = ListTab.SelectedTab;
4311 RemoveSpecifiedTab(relTp.Text, false);
4313 e.SuppressKeyPress = true;
4317 public void AddNewTabForUserTimeline(string user)
4319 //同一検索条件のタブが既に存在すれば、そのタブアクティブにして終了
4320 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.UserTimeline))
4322 if (tb.User == user)
4324 foreach (TabPage tp in ListTab.TabPages)
4326 if (tb.TabName == tp.Text)
4328 ListTab.SelectedTab = tp;
4335 string tabName = "user:" + user;
4336 while (_statuses.ContainsTab(tabName))
4341 _statuses.AddTab(tabName, MyCommon.TabUsageType.UserTimeline, null);
4342 _statuses.Tabs[tabName].User = user;
4343 AddNewTab(tabName, false, MyCommon.TabUsageType.UserTimeline);
4345 ListTab.SelectedIndex = ListTab.TabPages.Count - 1;
4349 GetTimeline(MyCommon.WORKERTYPE.UserTimeline, 1, 0, tabName);
4352 public bool AddNewTab(string tabName, bool startup, MyCommon.TabUsageType tabType, ListElement listInfo = null)
4355 foreach (TabPage tb in ListTab.TabPages)
4357 if (tb.Text == tabName) return false;
4361 if (tabName == Properties.Resources.AddNewTabText1) return false;
4366 if (tabType == MyCommon.TabUsageType.DirectMessage ||
4367 tabType == MyCommon.TabUsageType.Favorites ||
4368 tabType == MyCommon.TabUsageType.Home ||
4369 tabType == MyCommon.TabUsageType.Mentions ||
4370 tabType == MyCommon.TabUsageType.Related)
4372 if (_statuses.GetTabByType(tabType) != null) return false;
4376 TabPage _tabPage = new TabPage();
4377 DetailsListView _listCustom = new DetailsListView();
4378 ColumnHeader _colHd1 = new ColumnHeader(); //アイコン
4379 ColumnHeader _colHd2 = new ColumnHeader(); //ニックネーム
4380 ColumnHeader _colHd3 = new ColumnHeader(); //本文
4381 ColumnHeader _colHd4 = new ColumnHeader(); //日付
4382 ColumnHeader _colHd5 = new ColumnHeader(); //ユーザID
4383 ColumnHeader _colHd6 = new ColumnHeader(); //未読
4384 ColumnHeader _colHd7 = new ColumnHeader(); //マーク&プロテクト
4385 ColumnHeader _colHd8 = new ColumnHeader(); //ソース
4387 int cnt = ListTab.TabPages.Count;
4389 ///ToDo:Create and set controls follow tabtypes
4391 this.SplitContainer1.Panel1.SuspendLayout();
4392 this.SplitContainer1.Panel2.SuspendLayout();
4393 this.SplitContainer1.SuspendLayout();
4394 this.ListTab.SuspendLayout();
4395 this.SuspendLayout();
4397 _tabPage.SuspendLayout();
4401 if (tabType == MyCommon.TabUsageType.UserTimeline || tabType == MyCommon.TabUsageType.Lists)
4403 label = new Label();
4404 label.Dock = DockStyle.Top;
4405 label.Name = "labelUser";
4406 if (tabType == MyCommon.TabUsageType.Lists)
4408 label.Text = listInfo.ToString();
4412 label.Text = _statuses.Tabs[tabName].User + "'s Timeline";
4414 label.TextAlign = ContentAlignment.MiddleLeft;
4415 using (ComboBox tmpComboBox = new ComboBox())
4417 label.Height = tmpComboBox.Height;
4419 _tabPage.Controls.Add(label);
4424 if (tabType == MyCommon.TabUsageType.PublicSearch)
4428 Label lbl = new Label();
4429 ComboBox cmb = new ComboBox();
4430 Button btn = new Button();
4431 ComboBox cmbLang = new ComboBox();
4433 pnl.SuspendLayout();
4435 pnl.Controls.Add(cmb);
4436 pnl.Controls.Add(cmbLang);
4437 pnl.Controls.Add(btn);
4438 pnl.Controls.Add(lbl);
4439 pnl.Name = "panelSearch";
4440 pnl.Dock = DockStyle.Top;
4441 pnl.Height = cmb.Height;
4442 pnl.Enter += SearchControls_Enter;
4443 pnl.Leave += SearchControls_Leave;
4446 cmb.Anchor = AnchorStyles.Left | AnchorStyles.Right;
4447 cmb.Dock = DockStyle.Fill;
4448 cmb.Name = "comboSearch";
4449 cmb.DropDownStyle = ComboBoxStyle.DropDown;
4450 cmb.ImeMode = ImeMode.NoControl;
4451 cmb.TabStop = false;
4452 cmb.AutoCompleteMode = AutoCompleteMode.None;
4453 cmb.KeyDown += SearchComboBox_KeyDown;
4455 if (_statuses.ContainsTab(tabName))
4457 cmb.Items.Add(_statuses.Tabs[tabName].SearchWords);
4458 cmb.Text = _statuses.Tabs[tabName].SearchWords;
4462 cmbLang.Anchor = AnchorStyles.Left | AnchorStyles.Right;
4463 cmbLang.Dock = DockStyle.Right;
4465 cmbLang.Name = "comboLang";
4466 cmbLang.DropDownStyle = ComboBoxStyle.DropDownList;
4467 cmbLang.TabStop = false;
4468 cmbLang.Items.Add("");
4469 cmbLang.Items.Add("ja");
4470 cmbLang.Items.Add("en");
4471 cmbLang.Items.Add("ar");
4472 cmbLang.Items.Add("da");
4473 cmbLang.Items.Add("nl");
4474 cmbLang.Items.Add("fa");
4475 cmbLang.Items.Add("fi");
4476 cmbLang.Items.Add("fr");
4477 cmbLang.Items.Add("de");
4478 cmbLang.Items.Add("hu");
4479 cmbLang.Items.Add("is");
4480 cmbLang.Items.Add("it");
4481 cmbLang.Items.Add("no");
4482 cmbLang.Items.Add("pl");
4483 cmbLang.Items.Add("pt");
4484 cmbLang.Items.Add("ru");
4485 cmbLang.Items.Add("es");
4486 cmbLang.Items.Add("sv");
4487 cmbLang.Items.Add("th");
4488 if (_statuses.ContainsTab(tabName)) cmbLang.Text = _statuses.Tabs[tabName].SearchLang;
4490 lbl.Text = "Search(C-S-f)";
4491 lbl.Name = "label1";
4492 lbl.Dock = DockStyle.Left;
4494 lbl.Height = cmb.Height;
4495 lbl.TextAlign = ContentAlignment.MiddleLeft;
4497 btn.Text = "Search";
4498 btn.Name = "buttonSearch";
4499 btn.UseVisualStyleBackColor = true;
4500 btn.Dock = DockStyle.Right;
4501 btn.TabStop = false;
4502 btn.Click += SearchButton_Click;
4505 this.ListTab.Controls.Add(_tabPage);
4506 _tabPage.Controls.Add(_listCustom);
4508 if (tabType == MyCommon.TabUsageType.PublicSearch) _tabPage.Controls.Add(pnl);
4509 if (tabType == MyCommon.TabUsageType.UserTimeline || tabType == MyCommon.TabUsageType.Lists) _tabPage.Controls.Add(label);
4511 _tabPage.Location = new Point(4, 4);
4512 _tabPage.Name = "CTab" + cnt.ToString();
4513 _tabPage.Size = new Size(380, 260);
4514 _tabPage.TabIndex = 2 + cnt;
4515 _tabPage.Text = tabName;
4516 _tabPage.UseVisualStyleBackColor = true;
4518 _listCustom.AllowColumnReorder = true;
4521 _listCustom.Columns.AddRange(new ColumnHeader[] {_colHd1, _colHd2, _colHd3, _colHd4, _colHd5, _colHd6, _colHd7, _colHd8});
4525 _listCustom.Columns.AddRange(new ColumnHeader[] {_colHd1, _colHd3});
4527 _listCustom.ContextMenuStrip = this.ContextMenuOperate;
4528 _listCustom.Dock = DockStyle.Fill;
4529 _listCustom.FullRowSelect = true;
4530 _listCustom.HideSelection = false;
4531 _listCustom.Location = new Point(0, 0);
4532 _listCustom.Margin = new Padding(0);
4533 _listCustom.Name = "CList" + Environment.TickCount.ToString();
4534 _listCustom.ShowItemToolTips = true;
4535 _listCustom.Size = new Size(380, 260);
4536 _listCustom.UseCompatibleStateImageBehavior = false;
4537 _listCustom.View = View.Details;
4538 _listCustom.OwnerDraw = true;
4539 _listCustom.VirtualMode = true;
4540 _listCustom.Font = _fntReaded;
4541 _listCustom.BackColor = _clListBackcolor;
4543 _listCustom.GridLines = SettingDialog.ShowGrid;
4544 _listCustom.AllowDrop = true;
4546 _listCustom.SelectedIndexChanged += MyList_SelectedIndexChanged;
4547 _listCustom.MouseDoubleClick += MyList_MouseDoubleClick;
4548 _listCustom.ColumnClick += MyList_ColumnClick;
4549 _listCustom.DrawColumnHeader += MyList_DrawColumnHeader;
4550 _listCustom.DragDrop += TweenMain_DragDrop;
4551 _listCustom.DragOver += TweenMain_DragOver;
4552 _listCustom.DrawItem += MyList_DrawItem;
4553 _listCustom.MouseClick += MyList_MouseClick;
4554 _listCustom.ColumnReordered += MyList_ColumnReordered;
4555 _listCustom.ColumnWidthChanged += MyList_ColumnWidthChanged;
4556 _listCustom.CacheVirtualItems += MyList_CacheVirtualItems;
4557 _listCustom.RetrieveVirtualItem += MyList_RetrieveVirtualItem;
4558 _listCustom.DrawSubItem += MyList_DrawSubItem;
4559 _listCustom.HScrolled += MyList_HScrolled;
4562 _colHd1.Text = ColumnText[0];
4564 _colHd2.Text = ColumnText[1];
4566 _colHd3.Text = ColumnText[2];
4567 _colHd3.Width = 300;
4568 _colHd4.Text = ColumnText[3];
4570 _colHd5.Text = ColumnText[4];
4572 _colHd6.Text = ColumnText[5];
4574 _colHd7.Text = ColumnText[6];
4576 _colHd8.Text = ColumnText[7];
4579 _listCustom.SmallImageList = new ImageList();
4582 _listCustom.SmallImageList.ImageSize = new Size(_iconSz, _iconSz);
4586 _listCustom.SmallImageList.ImageSize = new Size(1, 1);
4589 int[] dispOrder = new int[8];
4592 for (int i = 0; i < _curList.Columns.Count; i++)
4594 for (int j = 0; j < _curList.Columns.Count; j++)
4596 if (_curList.Columns[j].DisplayIndex == i)
4603 for (int i = 0; i < _curList.Columns.Count; i++)
4605 _listCustom.Columns[i].Width = _curList.Columns[i].Width;
4606 _listCustom.Columns[dispOrder[i]].DisplayIndex = i;
4613 _listCustom.Columns[0].Width = _cfgLocal.Width1;
4614 _listCustom.Columns[1].Width = _cfgLocal.Width3;
4615 _listCustom.Columns[0].DisplayIndex = 0;
4616 _listCustom.Columns[1].DisplayIndex = 1;
4620 for (int i = 0; i <= 7; i++)
4622 if (_cfgLocal.DisplayIndex1 == i)
4624 else if (_cfgLocal.DisplayIndex2 == i)
4626 else if (_cfgLocal.DisplayIndex3 == i)
4628 else if (_cfgLocal.DisplayIndex4 == i)
4630 else if (_cfgLocal.DisplayIndex5 == i)
4632 else if (_cfgLocal.DisplayIndex6 == i)
4634 else if (_cfgLocal.DisplayIndex7 == i)
4636 else if (_cfgLocal.DisplayIndex8 == i)
4639 _listCustom.Columns[0].Width = _cfgLocal.Width1;
4640 _listCustom.Columns[1].Width = _cfgLocal.Width2;
4641 _listCustom.Columns[2].Width = _cfgLocal.Width3;
4642 _listCustom.Columns[3].Width = _cfgLocal.Width4;
4643 _listCustom.Columns[4].Width = _cfgLocal.Width5;
4644 _listCustom.Columns[5].Width = _cfgLocal.Width6;
4645 _listCustom.Columns[6].Width = _cfgLocal.Width7;
4646 _listCustom.Columns[7].Width = _cfgLocal.Width8;
4647 for (int i = 0; i <= 7; i++)
4649 _listCustom.Columns[dispOrder[i]].DisplayIndex = i;
4654 if (tabType == MyCommon.TabUsageType.PublicSearch) pnl.ResumeLayout(false);
4656 _tabPage.ResumeLayout(false);
4658 this.SplitContainer1.Panel1.ResumeLayout(false);
4659 this.SplitContainer1.Panel2.ResumeLayout(false);
4660 this.SplitContainer1.ResumeLayout(false);
4661 this.ListTab.ResumeLayout(false);
4662 this.ResumeLayout(false);
4663 this.PerformLayout();
4664 _tabPage.Tag = _listCustom;
4668 public bool RemoveSpecifiedTab(string TabName, bool confirm)
4671 for (idx = 0; idx < ListTab.TabPages.Count; idx++)
4673 if (ListTab.TabPages[idx].Text == TabName) break;
4676 if (_statuses.IsDefaultTab(TabName) || _statuses.Tabs[TabName].Protected) return false;
4680 string tmp = string.Format(Properties.Resources.RemoveSpecifiedTabText1, Environment.NewLine);
4681 if (MessageBox.Show(tmp, TabName + " " + Properties.Resources.RemoveSpecifiedTabText2,
4682 MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Cancel)
4688 SetListProperty(); //他のタブに列幅等を反映
4690 MyCommon.TabUsageType tabType = _statuses.Tabs[TabName].TabType;
4693 this.SplitContainer1.Panel1.SuspendLayout();
4694 this.SplitContainer1.Panel2.SuspendLayout();
4695 this.SplitContainer1.SuspendLayout();
4696 this.ListTab.SuspendLayout();
4697 this.SuspendLayout();
4699 TabPage _tabPage = ListTab.TabPages[idx];
4700 DetailsListView _listCustom = (DetailsListView)_tabPage.Tag;
4701 _tabPage.Tag = null;
4703 _tabPage.SuspendLayout();
4705 if (this.ListTab.SelectedTab == this.ListTab.TabPages[idx])
4707 this.ListTab.SelectTab((this._beforeSelectedTab != null && this.ListTab.TabPages.Contains(this._beforeSelectedTab)) ? this._beforeSelectedTab : this.ListTab.TabPages[0]);
4709 this.ListTab.Controls.Remove(_tabPage);
4712 if (tabType == MyCommon.TabUsageType.PublicSearch)
4714 pnl = _tabPage.Controls["panelSearch"];
4715 foreach (Control ctrl in pnl.Controls)
4717 if (ctrl.Name == "buttonSearch")
4719 ctrl.Click -= SearchButton_Click;
4721 ctrl.Enter -= SearchControls_Enter;
4722 ctrl.Leave -= SearchControls_Leave;
4723 pnl.Controls.Remove(ctrl);
4726 _tabPage.Controls.Remove(pnl);
4729 _tabPage.Controls.Remove(_listCustom);
4730 _listCustom.Columns.Clear();
4731 _listCustom.ContextMenuStrip = null;
4733 _listCustom.SelectedIndexChanged -= MyList_SelectedIndexChanged;
4734 _listCustom.MouseDoubleClick -= MyList_MouseDoubleClick;
4735 _listCustom.ColumnClick -= MyList_ColumnClick;
4736 _listCustom.DrawColumnHeader -= MyList_DrawColumnHeader;
4737 _listCustom.DragDrop -= TweenMain_DragDrop;
4738 _listCustom.DragOver -= TweenMain_DragOver;
4739 _listCustom.DrawItem -= MyList_DrawItem;
4740 _listCustom.MouseClick -= MyList_MouseClick;
4741 _listCustom.ColumnReordered -= MyList_ColumnReordered;
4742 _listCustom.ColumnWidthChanged -= MyList_ColumnWidthChanged;
4743 _listCustom.CacheVirtualItems -= MyList_CacheVirtualItems;
4744 _listCustom.RetrieveVirtualItem -= MyList_RetrieveVirtualItem;
4745 _listCustom.DrawSubItem -= MyList_DrawSubItem;
4746 _listCustom.HScrolled -= MyList_HScrolled;
4748 _listCustom.SmallImageList = null;
4749 _listCustom.ListViewItemSorter = null;
4752 if (_curTab.Equals(_tabPage))
4759 this.PurgeListViewItemCache();
4761 _tabPage.ResumeLayout(false);
4763 this.SplitContainer1.Panel1.ResumeLayout(false);
4764 this.SplitContainer1.Panel2.ResumeLayout(false);
4765 this.SplitContainer1.ResumeLayout(false);
4766 this.ListTab.ResumeLayout(false);
4767 this.ResumeLayout(false);
4768 this.PerformLayout();
4771 _listCustom.Dispose();
4772 _statuses.RemoveTab(TabName);
4774 foreach (TabPage tp in ListTab.TabPages)
4776 DetailsListView lst = (DetailsListView)tp.Tag;
4777 if (lst.VirtualListSize != _statuses.Tabs[tp.Text].AllCount)
4779 lst.VirtualListSize = _statuses.Tabs[tp.Text].AllCount;
4786 private void ListTab_Deselected(object sender, TabControlEventArgs e)
4788 this.PurgeListViewItemCache();
4789 _beforeSelectedTab = e.TabPage;
4792 private void ListTab_MouseMove(object sender, MouseEventArgs e)
4796 if (!SettingDialog.TabMouseLock && e.Button == MouseButtons.Left && _tabDrag)
4799 Rectangle dragEnableRectangle = new Rectangle((int)(_tabMouseDownPoint.X - (SystemInformation.DragSize.Width / 2)), (int)(_tabMouseDownPoint.Y - (SystemInformation.DragSize.Height / 2)), SystemInformation.DragSize.Width, SystemInformation.DragSize.Height);
4800 if (!dragEnableRectangle.Contains(e.Location))
4802 //タブが多段の場合にはMouseDownの前の段階で選択されたタブの段が変わっているので、このタイミングでカーソルの位置からタブを判定出来ない。
4803 tn = ListTab.SelectedTab.Text;
4806 if (string.IsNullOrEmpty(tn)) return;
4808 foreach (TabPage tb in ListTab.TabPages)
4812 ListTab.DoDragDrop(tb, DragDropEffects.All);
4822 Point cpos = new Point(e.X, e.Y);
4823 for (int i = 0; i < ListTab.TabPages.Count; i++)
4825 Rectangle rect = ListTab.GetTabRect(i);
4826 if (rect.Left <= cpos.X & cpos.X <= rect.Right &
4827 rect.Top <= cpos.Y & cpos.Y <= rect.Bottom)
4829 _rclickTabName = ListTab.TabPages[i].Text;
4835 private void ListTab_SelectedIndexChanged(object sender, EventArgs e)
4837 //_curList.Refresh();
4839 SetMainWindowTitle();
4840 SetStatusLabelUrl();
4841 if (ListTab.Focused || ((Control)ListTab.SelectedTab.Tag).Focused) this.Tag = ListTab.Tag;
4842 TabMenuControl(ListTab.SelectedTab.Text);
4843 this.PushSelectPostChain();
4846 private void SetListProperty()
4848 //削除などで見つからない場合は処理せず
4849 if (_curList == null) return;
4850 if (!_isColumnChanged) return;
4852 int[] dispOrder = new int[_curList.Columns.Count];
4853 for (int i = 0; i < _curList.Columns.Count; i++)
4855 for (int j = 0; j < _curList.Columns.Count; j++)
4857 if (_curList.Columns[j].DisplayIndex == i)
4866 foreach (TabPage tb in ListTab.TabPages)
4868 if (!tb.Equals(_curTab))
4870 if (tb.Tag != null && tb.Controls.Count > 0)
4872 DetailsListView lst = (DetailsListView)tb.Tag;
4873 for (int i = 0; i < lst.Columns.Count; i++)
4875 lst.Columns[dispOrder[i]].DisplayIndex = i;
4876 lst.Columns[i].Width = _curList.Columns[i].Width;
4882 _isColumnChanged = false;
4885 private void PostBrowser_StatusTextChanged(object sender, EventArgs e)
4889 if (PostBrowser.StatusText.StartsWith("http") || PostBrowser.StatusText.StartsWith("ftp")
4890 || PostBrowser.StatusText.StartsWith("data"))
4892 StatusLabelUrl.Text = PostBrowser.StatusText.Replace("&", "&&");
4894 if (string.IsNullOrEmpty(PostBrowser.StatusText))
4896 SetStatusLabelUrl();
4904 private void StatusText_KeyPress(object sender, KeyPressEventArgs e)
4906 if (e.KeyChar == '@')
4908 if (!SettingDialog.UseAtIdSupplement) return;
4910 int cnt = AtIdSupl.ItemCount;
4911 ShowSuplDialog(StatusText, AtIdSupl);
4912 if (cnt != AtIdSupl.ItemCount) _modifySettingAtId = true;
4915 else if (e.KeyChar == '#')
4917 if (!SettingDialog.UseHashSupplement) return;
4918 ShowSuplDialog(StatusText, HashSupl);
4923 public void ShowSuplDialog(TextBox owner, AtIdSupplement dialog)
4925 ShowSuplDialog(owner, dialog, 0, "");
4928 public void ShowSuplDialog(TextBox owner, AtIdSupplement dialog, int offset)
4930 ShowSuplDialog(owner, dialog, offset, "");
4933 public void ShowSuplDialog(TextBox owner, AtIdSupplement dialog, int offset, string startswith)
4935 dialog.StartsWith = startswith;
4942 dialog.ShowDialog();
4944 this.TopMost = SettingDialog.AlwaysTop;
4945 int selStart = owner.SelectionStart;
4948 if (dialog.DialogResult == DialogResult.OK)
4950 if (!string.IsNullOrEmpty(dialog.inputText))
4954 fHalf = owner.Text.Substring(0, selStart - offset);
4956 if (selStart < owner.Text.Length)
4958 eHalf = owner.Text.Substring(selStart);
4960 owner.Text = fHalf + dialog.inputText + eHalf;
4961 owner.SelectionStart = selStart + dialog.inputText.Length;
4968 fHalf = owner.Text.Substring(0, selStart);
4970 if (selStart < owner.Text.Length)
4972 eHalf = owner.Text.Substring(selStart);
4974 owner.Text = fHalf + eHalf;
4977 owner.SelectionStart = selStart;
4983 private void StatusText_KeyUp(object sender, KeyEventArgs e)
4986 if (!e.Alt && !e.Control && !e.Shift)
4988 if (e.KeyCode == Keys.Space || e.KeyCode == Keys.ProcessKey)
4990 bool isSpace = false;
4991 foreach (char c in StatusText.Text.ToCharArray())
4993 if (c == ' ' || c == ' ')
5006 StatusText.Text = "";
5007 JumpUnreadMenuItem_Click(null, null);
5011 this.StatusText_TextChanged(null, null);
5014 private void StatusText_TextChanged(object sender, EventArgs e)
5017 int pLen = GetRestStatusCount(true, false);
5018 lblLen.Text = pLen.ToString();
5021 StatusText.ForeColor = Color.Red;
5025 StatusText.ForeColor = _clInputFont;
5027 if (string.IsNullOrEmpty(StatusText.Text))
5030 _reply_to_name = "";
5034 private int GetRestStatusCount(bool isAuto, bool isAddFooter)
5037 int pLen = 140 - StatusText.Text.Length;
5038 if (this.NotifyIcon1 == null || !this.NotifyIcon1.Visible) return pLen;
5039 if ((isAuto && !MyCommon.IsKeyDown(Keys.Control) && SettingDialog.PostShiftEnter) ||
5040 (isAuto && !MyCommon.IsKeyDown(Keys.Shift) && !SettingDialog.PostShiftEnter) ||
5041 (!isAuto && isAddFooter))
5043 if (SettingDialog.UseRecommendStatus)
5044 pLen -= SettingDialog.RecommendStatusText.Length;
5045 else if (SettingDialog.Status.Length > 0)
5046 pLen -= SettingDialog.Status.Length + 1;
5048 if (!string.IsNullOrEmpty(HashMgr.UseHash))
5050 pLen -= HashMgr.UseHash.Length + 1;
5052 //foreach (Match m in Regex.Matches(StatusText.Text, "https?:\/\/[-_.!~*//()a-zA-Z0-9;\/?:\@&=+\$,%#^]+"))
5054 // pLen += m.Length - SettingDialog.TwitterConfiguration.ShortUrlLength;
5056 foreach (Match m in Regex.Matches(StatusText.Text, Twitter.rgUrl, RegexOptions.IgnoreCase))
5058 string before = m.Result("${before}");
5059 string url = m.Result("${url}");
5060 string protocol = m.Result("${protocol}");
5061 string domain = m.Result("${domain}");
5062 string path = m.Result("${path}");
5063 if (protocol.Length == 0)
5065 if (Regex.IsMatch(before, Twitter.url_invalid_without_protocol_preceding_chars))
5070 bool last_url_invalid_match = false;
5071 string lasturl = null;
5072 foreach (Match mm in Regex.Matches(domain, Twitter.url_valid_ascii_domain, RegexOptions.IgnoreCase))
5074 lasturl = mm.ToString();
5075 last_url_invalid_match = Regex.IsMatch(lasturl, Twitter.url_invalid_short_domain, RegexOptions.IgnoreCase);
5076 if (!last_url_invalid_match)
5078 pLen += lasturl.Length - SettingDialog.TwitterConfiguration.ShortUrlLength;
5082 if (path.Length != 0)
5084 if (last_url_invalid_match)
5086 pLen += lasturl.Length - SettingDialog.TwitterConfiguration.ShortUrlLength;
5088 pLen += path.Length;
5093 pLen += url.Length - SettingDialog.TwitterConfiguration.ShortUrlLength;
5096 //if (m.Result("${url}").Length > SettingDialog.TwitterConfiguration.ShortUrlLength)
5098 // pLen += m.Result("${url}").Length - SettingDialog.TwitterConfiguration.ShortUrlLength;
5101 if (ImageSelectionPanel.Visible && ImageSelectedPicture.Tag != null && !string.IsNullOrEmpty(this.ImageService))
5103 pLen -= SettingDialog.TwitterConfiguration.CharactersReservedPerMedia;
5108 private void MyList_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e)
5110 this.itemCacheLock.EnterUpgradeableReadLock();
5113 if (_itemCache != null &&
5114 e.StartIndex >= _itemCacheIndex &&
5115 e.EndIndex < _itemCacheIndex + _itemCache.Length &&
5116 _curList.Equals(sender))
5118 //If the newly requested cache is a subset of the old cache,
5119 //no need to rebuild everything, so do nothing.
5123 //Now we need to rebuild the cache.
5124 if (_curList.Equals(sender)) CreateCache(e.StartIndex, e.EndIndex);
5126 finally { this.itemCacheLock.ExitUpgradeableReadLock(); }
5129 private void MyList_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
5131 ListViewItem cacheItem = null;
5132 PostClass cacheItemPost = null;
5134 this.TryGetListViewItemCache(e.ItemIndex, out cacheItem, out cacheItemPost);
5136 if (cacheItem != null)
5142 //A cache miss, so create a new ListViewItem and pass it back.
5143 TabPage tb = (TabPage)((DetailsListView)sender).Parent;
5146 e.Item = CreateItem(tb,
5147 _statuses[tb.Text, e.ItemIndex],
5153 string[] sitem = {"", "", "", "", "", "", "", ""};
5154 e.Item = new ImageListViewItem(sitem, "");
5159 private void CreateCache(int StartIndex, int EndIndex)
5161 this.itemCacheLock.EnterWriteLock();
5164 //キャッシュ要求(要求範囲±30を作成)
5166 if (StartIndex < 0) StartIndex = 0;
5168 if (EndIndex >= _statuses.Tabs[_curTab.Text].AllCount) EndIndex = _statuses.Tabs[_curTab.Text].AllCount - 1;
5169 _postCache = _statuses[_curTab.Text, StartIndex, EndIndex]; //配列で取得
5170 _itemCacheIndex = StartIndex;
5172 _itemCache = new ListViewItem[0] {};
5173 Array.Resize(ref _itemCache, _postCache.Length);
5175 for (int i = 0; i < _postCache.Length; i++)
5177 _itemCache[i] = CreateItem(_curTab, _postCache[i], StartIndex + i);
5182 //キャッシュ要求が実データとずれるため(イベントの遅延?)
5186 finally { this.itemCacheLock.ExitWriteLock(); }
5190 /// DetailsListView のための ListViewItem のキャッシュを消去する
5192 private void PurgeListViewItemCache()
5194 this.itemCacheLock.EnterWriteLock();
5197 this._itemCache = null;
5198 this._itemCacheIndex = -1;
5199 this._postCache = null;
5201 finally { this.itemCacheLock.ExitWriteLock(); }
5204 private bool TryGetListViewItemCache(int index, out ListViewItem item, out PostClass post)
5206 this.itemCacheLock.EnterReadLock();
5209 if (this._itemCache != null && index >= this._itemCacheIndex && index < this._itemCacheIndex + this._itemCache.Length)
5211 item = this._itemCache[index - _itemCacheIndex];
5212 post = this._postCache[index - _itemCacheIndex];
5216 finally { this.itemCacheLock.ExitReadLock(); }
5223 private ListViewItem CreateItem(TabPage Tab, PostClass Post, int Index)
5225 StringBuilder mk = new StringBuilder();
5226 //if (Post.IsDeleted) mk.Append("×");
5227 //if (Post.IsMark) mk.Append("♪");
5228 //if (Post.IsProtect) mk.Append("Ю");
5229 //if (Post.InReplyToStatusId > 0) mk.Append("⇒");
5230 if (Post.FavoritedCount > 0) mk.Append("+" + Post.FavoritedCount.ToString());
5231 ImageListViewItem itm;
5232 if (Post.RetweetedId == 0)
5234 string[] sitem= {"",
5236 Post.IsDeleted ? "(DELETED)" : Post.TextSingleLine,
5237 Post.CreatedAt.ToString(SettingDialog.DateTimeFormat),
5242 itm = new ImageListViewItem(sitem, this.IconCache, Post.ImageUrl);
5246 string[] sitem = {"",
5248 Post.IsDeleted ? "(DELETED)" : Post.TextSingleLine,
5249 Post.CreatedAt.ToString(SettingDialog.DateTimeFormat),
5250 Post.ScreenName + Environment.NewLine + "(RT:" + Post.RetweetedBy + ")",
5254 itm = new ImageListViewItem(sitem, this.IconCache, Post.ImageUrl);
5256 itm.StateImageIndex = Post.StateIndex;
5258 bool read = Post.IsRead;
5259 //未読管理していなかったら既読として扱う
5260 if (!_statuses.Tabs[Tab.Text].UnreadManage || !SettingDialog.UnreadManage) read = true;
5261 ChangeItemStyleRead(read, itm, Post, null);
5262 if (Tab.Equals(_curTab)) ColorizeList(itm, Index);
5266 private void MyList_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
5268 e.DrawDefault = true;
5271 private void MyList_HScrolled(object sender, EventArgs e)
5273 DetailsListView listView = (DetailsListView)sender;
5277 private void MyList_DrawItem(object sender, DrawListViewItemEventArgs e)
5279 if (e.State == 0) return;
5280 e.DrawDefault = false;
5281 if (!e.Item.Selected) //e.ItemStateでうまく判定できない???
5283 SolidBrush brs2 = null;
5285 if (e.Item.BackColor == _clSelf)
5286 brs2 = _brsBackColorMine;
5287 else if (e.Item.BackColor == _clAtSelf)
5288 brs2 = _brsBackColorAt;
5289 else if (e.Item.BackColor == _clTarget)
5290 brs2 = _brsBackColorYou;
5291 else if (e.Item.BackColor == _clAtTarget)
5292 brs2 = _brsBackColorAtYou;
5293 else if (e.Item.BackColor == _clAtFromTarget)
5294 brs2 = _brsBackColorAtFromTarget;
5295 else if (e.Item.BackColor == _clAtTo)
5296 brs2 = _brsBackColorAtTo;
5298 brs2 = _brsBackColorNone;
5300 e.Graphics.FillRectangle(brs2, e.Bounds);
5305 if (((Control)sender).Focused)
5306 e.Graphics.FillRectangle(_brsHighLight, e.Bounds);
5308 e.Graphics.FillRectangle(_brsDeactiveSelection, e.Bounds);
5310 if ((e.State & ListViewItemStates.Focused) == ListViewItemStates.Focused) e.DrawFocusRectangle();
5311 this.DrawListViewItemIcon(e);
5314 private void MyList_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
5316 if (e.ItemState == 0) return;
5318 if (e.ColumnIndex > 0)
5321 RectangleF rct = e.Bounds;
5322 RectangleF rctB = e.Bounds;
5323 rct.Width = e.Header.Width;
5324 rctB.Width = e.Header.Width;
5327 rct.Y += e.Item.Font.Height;
5328 rct.Height -= e.Item.Font.Height;
5329 rctB.Height = e.Item.Font.Height;
5334 int drawLineCount = Math.Max(1, Math.DivRem((int)rct.Height, e.Item.Font.Height, out heightDiff));
5336 //if (heightDiff > e.Item.Font.Height * 0.7)
5338 // rct.Height += e.Item.Font.Height;
5339 // drawLineCount += 1;
5342 //フォントの高さの半分を足してるのは保険。無くてもいいかも。
5343 if (!_iconCol && drawLineCount <= 1)
5345 //rct.Inflate(0, heightDiff / -2);
5346 //rct.Height += e.Item.Font.Height / 2;
5348 else if (heightDiff < e.Item.Font.Height * 0.7)
5350 //最終行が70%以上欠けていたら、最終行は表示しない
5351 //rct.Height = (float)((e.Item.Font.Height * drawLineCount) + (e.Item.Font.Height / 2));
5352 rct.Height = (e.Item.Font.Height * drawLineCount) - 1;
5359 //if (!_iconCol && drawLineCount > 1)
5361 // rct.Y += e.Item.Font.Height * 0.2;
5362 // if (heightDiff >= e.Item.Font.Height * 0.8) rct.Height -= e.Item.Font.Height * 0.2;
5364 if (!e.Item.Selected) //e.ItemStateでうまく判定できない???
5368 SolidBrush brs = null;
5371 if (e.Item.ForeColor == _clUnread)
5373 brs = _brsForeColorUnread;
5375 else if (e.Item.ForeColor == _clReaded)
5377 brs = _brsForeColorReaded;
5379 else if (e.Item.ForeColor == _clFav)
5381 brs = _brsForeColorFav;
5383 else if (e.Item.ForeColor == _clOWL)
5385 brs = _brsForeColorOWL;
5387 else if (e.Item.ForeColor == _clRetweet)
5389 brs = _brsForeColorRetweet;
5393 brs = new SolidBrush(e.Item.ForeColor);
5401 using (Font fnt = new Font(e.Item.Font, FontStyle.Bold))
5403 //e.Graphics.DrawString(System.Environment.NewLine + e.Item.SubItems[2].Text, e.Item.Font, brs, rct, sf);
5404 //e.Graphics.DrawString(e.Item.SubItems[4].Text + " / " + e.Item.SubItems[1].Text + " (" + e.Item.SubItems[3].Text + ") " + e.Item.SubItems[5].Text + e.Item.SubItems[6].Text + " [" + e.Item.SubItems[7].Text + "]", fnt, brs, rctB, sf);
5405 TextRenderer.DrawText(e.Graphics,
5406 e.Item.SubItems[2].Text,
5408 Rectangle.Round(rct),
5410 TextFormatFlags.WordBreak |
5411 TextFormatFlags.EndEllipsis |
5412 TextFormatFlags.GlyphOverhangPadding |
5413 TextFormatFlags.NoPrefix);
5414 TextRenderer.DrawText(e.Graphics,
5415 e.Item.SubItems[4].Text + " / " + e.Item.SubItems[1].Text + " (" + e.Item.SubItems[3].Text + ") " + e.Item.SubItems[5].Text + e.Item.SubItems[6].Text + " [" + e.Item.SubItems[7].Text + "]",
5417 Rectangle.Round(rctB),
5419 TextFormatFlags.SingleLine |
5420 TextFormatFlags.EndEllipsis |
5421 TextFormatFlags.GlyphOverhangPadding |
5422 TextFormatFlags.NoPrefix);
5425 else if (drawLineCount == 1)
5427 TextRenderer.DrawText(e.Graphics,
5430 Rectangle.Round(rct),
5432 TextFormatFlags.SingleLine |
5433 TextFormatFlags.EndEllipsis |
5434 TextFormatFlags.GlyphOverhangPadding |
5435 TextFormatFlags.NoPrefix |
5436 TextFormatFlags.VerticalCenter);
5440 //e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, brs, rct, sf);
5441 TextRenderer.DrawText(e.Graphics,
5444 Rectangle.Round(rct),
5446 TextFormatFlags.WordBreak |
5447 TextFormatFlags.EndEllipsis |
5448 TextFormatFlags.GlyphOverhangPadding |
5449 TextFormatFlags.NoPrefix);
5452 if (flg) brs.Dispose();
5459 using (Font fnt = new Font(e.Item.Font, FontStyle.Bold))
5461 if (((Control)sender).Focused)
5465 //e.Graphics.DrawString(System.Environment.NewLine + e.Item.SubItems[2].Text, e.Item.Font, _brsHighLightText, rct, sf);
5466 //e.Graphics.DrawString(e.Item.SubItems[4].Text + " / " + e.Item.SubItems[1].Text + " (" + e.Item.SubItems[3].Text + ") " + e.Item.SubItems[5].Text + e.Item.SubItems[6].Text + " [" + e.Item.SubItems[7].Text + "]", fnt, _brsHighLightText, rctB, sf);
5467 TextRenderer.DrawText(e.Graphics,
5468 e.Item.SubItems[2].Text,
5470 Rectangle.Round(rct),
5471 _brsHighLightText.Color,
5472 TextFormatFlags.WordBreak |
5473 TextFormatFlags.EndEllipsis |
5474 TextFormatFlags.GlyphOverhangPadding |
5475 TextFormatFlags.NoPrefix);
5476 TextRenderer.DrawText(e.Graphics,
5477 e.Item.SubItems[4].Text + " / " + e.Item.SubItems[1].Text + " (" + e.Item.SubItems[3].Text + ") " + e.Item.SubItems[5].Text + e.Item.SubItems[6].Text + " [" + e.Item.SubItems[7].Text + "]",
5479 Rectangle.Round(rctB),
5480 _brsHighLightText.Color,
5481 TextFormatFlags.SingleLine |
5482 TextFormatFlags.EndEllipsis |
5483 TextFormatFlags.GlyphOverhangPadding |
5484 TextFormatFlags.NoPrefix);
5486 else if (drawLineCount == 1)
5488 TextRenderer.DrawText(e.Graphics,
5491 Rectangle.Round(rct),
5492 _brsHighLightText.Color,
5493 TextFormatFlags.SingleLine |
5494 TextFormatFlags.EndEllipsis |
5495 TextFormatFlags.GlyphOverhangPadding |
5496 TextFormatFlags.NoPrefix |
5497 TextFormatFlags.VerticalCenter);
5501 //e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, _brsHighLightText, rct, sf);
5502 TextRenderer.DrawText(e.Graphics,
5505 Rectangle.Round(rct),
5506 _brsHighLightText.Color,
5507 TextFormatFlags.WordBreak |
5508 TextFormatFlags.EndEllipsis |
5509 TextFormatFlags.GlyphOverhangPadding |
5510 TextFormatFlags.NoPrefix);
5517 //e.Graphics.DrawString(System.Environment.NewLine + e.Item.SubItems[2].Text, e.Item.Font, _brsForeColorUnread, rct, sf);
5518 //e.Graphics.DrawString(e.Item.SubItems[4].Text + " / " + e.Item.SubItems[1].Text + " (" + e.Item.SubItems[3].Text + ") " + e.Item.SubItems[5].Text + e.Item.SubItems[6].Text + " [" + e.Item.SubItems[7].Text + "]", fnt, _brsForeColorUnread, rctB, sf);
5519 TextRenderer.DrawText(e.Graphics,
5520 e.Item.SubItems[2].Text,
5522 Rectangle.Round(rct),
5523 _brsForeColorUnread.Color,
5524 TextFormatFlags.WordBreak |
5525 TextFormatFlags.EndEllipsis |
5526 TextFormatFlags.GlyphOverhangPadding |
5527 TextFormatFlags.NoPrefix);
5528 TextRenderer.DrawText(e.Graphics,
5529 e.Item.SubItems[4].Text + " / " + e.Item.SubItems[1].Text + " (" + e.Item.SubItems[3].Text + ") " + e.Item.SubItems[5].Text + e.Item.SubItems[6].Text + " [" + e.Item.SubItems[7].Text + "]",
5531 Rectangle.Round(rctB),
5532 _brsForeColorUnread.Color,
5533 TextFormatFlags.SingleLine |
5534 TextFormatFlags.EndEllipsis |
5535 TextFormatFlags.GlyphOverhangPadding |
5536 TextFormatFlags.NoPrefix);
5538 else if (drawLineCount == 1)
5540 TextRenderer.DrawText(e.Graphics,
5543 Rectangle.Round(rct),
5544 _brsForeColorUnread.Color,
5545 TextFormatFlags.SingleLine |
5546 TextFormatFlags.EndEllipsis |
5547 TextFormatFlags.GlyphOverhangPadding |
5548 TextFormatFlags.NoPrefix |
5549 TextFormatFlags.VerticalCenter);
5553 //e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, _brsForeColorUnread, rct, sf);
5554 TextRenderer.DrawText(e.Graphics,
5557 Rectangle.Round(rct),
5558 _brsForeColorUnread.Color,
5559 TextFormatFlags.WordBreak |
5560 TextFormatFlags.EndEllipsis |
5561 TextFormatFlags.GlyphOverhangPadding |
5562 TextFormatFlags.NoPrefix);
5568 //if (e.ColumnIndex == 6) this.DrawListViewItemStateIcon(e, rct);
5572 private void DrawListViewItemIcon(DrawListViewItemEventArgs e)
5574 ImageListViewItem item = (ImageListViewItem)e.Item;
5575 Rectangle stateRect;
5577 //e.Bounds.Leftが常に0を指すから自前で計算
5578 Rectangle itemRect = item.Bounds;
5579 itemRect.Width = e.Item.ListView.Columns[0].Width;
5581 foreach (ColumnHeader clm in e.Item.ListView.Columns)
5583 if (clm.DisplayIndex < e.Item.ListView.Columns[0].DisplayIndex)
5584 itemRect.X += clm.Width;
5588 if (item.Image != null)
5590 iconRect = Rectangle.Intersect(new Rectangle(e.Item.GetBounds(ItemBoundsPortion.Icon).Location, new Size(_iconSz, _iconSz)), itemRect);
5591 iconRect.Offset(0, Math.Max(0, (itemRect.Height - _iconSz) / 2));
5592 stateRect = Rectangle.Intersect(new Rectangle(iconRect.Location.X + _iconSz + 2, iconRect.Location.Y, 18, 16), itemRect);
5596 iconRect = Rectangle.Intersect(new Rectangle(e.Item.GetBounds(ItemBoundsPortion.Icon).Location, new Size(1, 1)), itemRect);
5597 //iconRect.Offset(0, Math.Max(0, (itemRect.Height - _iconSz) / 2));
5598 stateRect = Rectangle.Intersect(new Rectangle(iconRect.Location.X + _iconSz + 2, iconRect.Location.Y, 18, 16), itemRect);
5601 var img = item.Image;
5602 if (img != null && iconRect.Width > 0)
5604 e.Graphics.FillRectangle(Brushes.White, iconRect);
5605 e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
5608 e.Graphics.DrawImage(img.Image, iconRect);
5610 catch (ArgumentException)
5616 if (item.StateImageIndex > -1)
5618 if (stateRect.Width > 0)
5620 //e.Graphics.FillRectangle(Brushes.White, stateRect);
5621 //e.Graphics.InterpolationMode = Drawing2D.InterpolationMode.High;
5622 e.Graphics.DrawImage(this.PostStateImageList.Images[item.StateImageIndex], stateRect);
5627 //private void DrawListViewItemStateIcon(DrawListViewSubItemEventArgs e, RectangleF rct)
5629 // ImageListViewItem item = (ImageListViewItem)e.Item;
5630 // if (item.StateImageIndex > -1)
5632 // ////e.Bounds.Leftが常に0を指すから自前で計算
5633 // //Rectangle itemRect = item.Bounds;
5634 // //itemRect.Width = e.Item.ListView.Columns[4].Width;
5636 // //foreach (ColumnHeader clm in e.Item.ListView.Columns)
5638 // // if (clm.DisplayIndex < e.Item.ListView.Columns[4].DisplayIndex)
5640 // // itemRect.X += clm.Width;
5644 // //Rectangle iconRect = Rectangle.Intersect(new Rectangle(e.Item.GetBounds(ItemBoundsPortion.Icon).Location, new Size(_iconSz, _iconSz)), itemRect);
5645 // //iconRect.Offset(0, Math.Max(0, (itemRect.Height - _iconSz) / 2));
5647 // if (rct.Width > 0)
5649 // RectangleF stateRect = RectangleF.Intersect(rct, new RectangleF(rct.Location, new Size(18, 16)));
5650 // //e.Graphics.FillRectangle(Brushes.White, rct);
5651 // //e.Graphics.InterpolationMode = Drawing2D.InterpolationMode.High;
5652 // e.Graphics.DrawImage(this.PostStateImageList.Images(item.StateImageIndex), stateRect);
5657 private void DoTabSearch(string _word,
5667 if (_curList.VirtualListSize == 0)
5669 MessageBox.Show(Properties.Resources.DoTabSearchText2, Properties.Resources.DoTabSearchText3, MessageBoxButtons.OK, MessageBoxIcon.Information);
5672 if (_curList.SelectedIndices.Count > 0)
5674 cidx = _curList.SelectedIndices[0];
5676 toIdx = _curList.VirtualListSize;
5680 case SEARCHTYPE.DialogSearch: //ダイアログからの検索
5681 if (_curList.SelectedIndices.Count > 0)
5682 cidx = _curList.SelectedIndices[0];
5686 case SEARCHTYPE.NextSearch: //次を検索
5687 if (_curList.SelectedIndices.Count > 0)
5689 cidx = _curList.SelectedIndices[0] + 1;
5690 if (cidx > toIdx) cidx = toIdx;
5697 case SEARCHTYPE.PrevSearch: //前を検索
5698 if (_curList.SelectedIndices.Count > 0)
5700 cidx = _curList.SelectedIndices[0] - 1;
5701 if (cidx < 0) cidx = 0;
5712 RegexOptions regOpt = RegexOptions.None;
5713 StringComparison fndOpt = StringComparison.Ordinal;
5716 regOpt = RegexOptions.IgnoreCase;
5717 fndOpt = StringComparison.OrdinalIgnoreCase;
5728 _search = new Regex(_word, regOpt);
5729 for (int idx = cidx; idx != toIdx; idx += stp)
5734 post = _statuses[_curTab.Text, idx];
5740 if (_search.IsMatch(post.Nickname)
5741 || _search.IsMatch(post.TextFromApi)
5742 || _search.IsMatch(post.ScreenName))
5744 SelectListItem(_curList, idx);
5745 _curList.EnsureVisible(idx);
5750 catch (ArgumentException)
5752 MessageBox.Show(Properties.Resources.DoTabSearchText1, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
5759 for (int idx = cidx; idx != toIdx; idx += stp)
5764 post = _statuses[_curTab.Text, idx];
5770 if (post.Nickname.IndexOf(_word, fndOpt) > -1
5771 || post.TextFromApi.IndexOf(_word, fndOpt) > -1
5772 || post.ScreenName.IndexOf(_word, fndOpt) > -1)
5774 SelectListItem(_curList, idx);
5775 _curList.EnsureVisible(idx);
5785 case SEARCHTYPE.DialogSearch:
5786 case SEARCHTYPE.NextSearch:
5790 case SEARCHTYPE.PrevSearch:
5792 cidx = _curList.Items.Count - 1;
5799 catch (ArgumentOutOfRangeException)
5802 MessageBox.Show(Properties.Resources.DoTabSearchText2, Properties.Resources.DoTabSearchText3, MessageBoxButtons.OK, MessageBoxIcon.Information);
5805 private void MenuItemSubSearch_Click(object sender, EventArgs e)
5808 SearchDialog.Owner = this;
5809 if (SearchDialog.ShowDialog() == DialogResult.Cancel)
5811 this.TopMost = SettingDialog.AlwaysTop;
5814 this.TopMost = SettingDialog.AlwaysTop;
5816 if (!string.IsNullOrEmpty(SearchDialog.SWord))
5818 DoTabSearch(SearchDialog.SWord,
5819 SearchDialog.CheckCaseSensitive,
5820 SearchDialog.CheckRegex,
5821 SEARCHTYPE.DialogSearch);
5825 private void MenuItemSearchNext_Click(object sender, EventArgs e)
5828 if (string.IsNullOrEmpty(SearchDialog.SWord))
5830 if (SearchDialog.ShowDialog() == DialogResult.Cancel)
5832 this.TopMost = SettingDialog.AlwaysTop;
5835 this.TopMost = SettingDialog.AlwaysTop;
5836 if (string.IsNullOrEmpty(SearchDialog.SWord)) return;
5838 DoTabSearch(SearchDialog.SWord,
5839 SearchDialog.CheckCaseSensitive,
5840 SearchDialog.CheckRegex,
5841 SEARCHTYPE.DialogSearch);
5845 DoTabSearch(SearchDialog.SWord,
5846 SearchDialog.CheckCaseSensitive,
5847 SearchDialog.CheckRegex,
5848 SEARCHTYPE.NextSearch);
5852 private void MenuItemSearchPrev_Click(object sender, EventArgs e)
5855 if (string.IsNullOrEmpty(SearchDialog.SWord))
5857 if (SearchDialog.ShowDialog() == DialogResult.Cancel)
5859 this.TopMost = SettingDialog.AlwaysTop;
5862 this.TopMost = SettingDialog.AlwaysTop;
5863 if (string.IsNullOrEmpty(SearchDialog.SWord)) return;
5866 DoTabSearch(SearchDialog.SWord,
5867 SearchDialog.CheckCaseSensitive,
5868 SearchDialog.CheckRegex,
5869 SEARCHTYPE.PrevSearch);
5872 private void AboutMenuItem_Click(object sender, EventArgs e)
5874 using (TweenAboutBox about = new TweenAboutBox())
5876 about.ShowDialog(this);
5878 this.TopMost = SettingDialog.AlwaysTop;
5881 private void JumpUnreadMenuItem_Click(object sender, EventArgs e)
5883 int bgnIdx = ListTab.TabPages.IndexOf(_curTab);
5885 DetailsListView lst = null;
5887 if (ImageSelectionPanel.Enabled)
5891 for (int i = bgnIdx; i < ListTab.TabPages.Count; i++)
5894 idx = _statuses.GetOldestUnreadIndex(ListTab.TabPages[i].Text);
5897 ListTab.SelectedIndex = i;
5898 lst = (DetailsListView)ListTab.TabPages[i].Tag;
5899 //_curTab = ListTab.TabPages[i];
5904 //未読みつからず&現在タブが先頭ではなかったら、先頭タブから現在タブの手前まで探索
5905 if (idx == -1 && bgnIdx > 0)
5907 for (int i = 0; i < bgnIdx; i++)
5909 idx = _statuses.GetOldestUnreadIndex(ListTab.TabPages[i].Text);
5912 ListTab.SelectedIndex = i;
5913 lst = (DetailsListView)ListTab.TabPages[i].Tag;
5914 //_curTab = ListTab.TabPages[i];
5920 //全部調べたが未読見つからず→先頭タブの最新発言へ
5923 ListTab.SelectedIndex = 0;
5924 lst = (DetailsListView)ListTab.TabPages[0].Tag;
5925 //_curTab = ListTab.TabPages[0];
5926 if (_statuses.SortOrder == SortOrder.Ascending)
5927 idx = lst.VirtualListSize - 1;
5932 if (lst.VirtualListSize > 0 && idx > -1 && lst.VirtualListSize > idx)
5934 SelectListItem(lst, idx);
5935 if (_statuses.SortMode == IdComparerClass.ComparerMode.Id)
5937 if (_statuses.SortOrder == SortOrder.Ascending && lst.Items[idx].Position.Y > lst.ClientSize.Height - _iconSz - 10 ||
5938 _statuses.SortOrder == SortOrder.Descending && lst.Items[idx].Position.Y < _iconSz + 10)
5944 lst.EnsureVisible(idx);
5949 lst.EnsureVisible(idx);
5955 private void StatusOpenMenuItem_Click(object sender, EventArgs e)
5957 if (_curList.SelectedIndices.Count > 0 && _statuses.Tabs[_curTab.Text].TabType != MyCommon.TabUsageType.DirectMessage)
5959 var post = _statuses[_curTab.Text, _curList.SelectedIndices[0]];
5960 OpenUriAsync(MyCommon.GetStatusUrl(post));
5964 private void FavorareMenuItem_Click(object sender, EventArgs e)
5966 if (_curList.SelectedIndices.Count > 0)
5968 PostClass post = _statuses[_curTab.Text, _curList.SelectedIndices[0]];
5969 OpenUriAsync(Properties.Resources.FavstarUrl + "users/" + post.ScreenName + "/recent");
5973 private void VerUpMenuItem_Click(object sender, EventArgs e)
5978 private void RunTweenUp()
5980 ProcessStartInfo pinfo = new ProcessStartInfo();
5981 pinfo.UseShellExecute = true;
5982 pinfo.WorkingDirectory = MyCommon.settingPath;
5983 pinfo.FileName = Path.Combine(MyCommon.settingPath, "TweenUp3.exe");
5984 pinfo.Arguments = "\"" + Application.StartupPath + "\"";
5987 Process.Start(pinfo);
5991 MessageBox.Show("Failed to execute TweenUp3.exe.");
5995 private void CheckNewVersion(bool startup = false)
5997 if (ApplicationSettings.VersionInfoUrl == null)
5998 return; // 更新チェック無効化
6000 if (string.IsNullOrEmpty(MyCommon.fileVersion))
6008 retMsg = tw.GetVersionInfo();
6015 if (string.IsNullOrEmpty(retMsg))
6017 StatusLabel.Text = Properties.Resources.CheckNewVersionText9;
6018 if (!startup) MessageBox.Show(Properties.Resources.CheckNewVersionText10, MyCommon.ReplaceAppName(Properties.Resources.CheckNewVersionText2), MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2);
6022 // 改行2つで前後パートを分割(前半がバージョン番号など、後半が詳細テキスト)
6023 string[] msgPart = retMsg.Split(new string[] {"\n\n", "\r\n\r\n"}, 2, StringSplitOptions.None);
6025 string[] msgHeader = msgPart[0].Split(new string[] {"\n", "\r\n"}, StringSplitOptions.None);
6026 string msgBody = msgPart.Length == 2 ? msgPart[1] : "";
6028 msgBody = Regex.Replace(msgBody, "(?<!\r)\n", "\r\n"); // LF -> CRLF
6030 string currentVersion = msgHeader[0];
6031 string downloadUrl = msgHeader[1];
6033 if (currentVersion.Replace(".", "").CompareTo(MyCommon.fileVersion.Replace(".", "")) > 0)
6035 using (var dialog = new UpdateDialog())
6037 dialog.SummaryText = string.Format(Properties.Resources.CheckNewVersionText3, MyCommon.GetReadableVersion(currentVersion));
6038 dialog.DetailsText = msgBody;
6039 if (dialog.ShowDialog(this) == DialogResult.Yes)
6041 this.OpenUriAsync(downloadUrl);
6049 var msgtext = MyCommon.ReplaceAppName(string.Format(Properties.Resources.CheckNewVersionText7, MyCommon.GetReadableVersion(), MyCommon.GetReadableVersion(currentVersion)));
6050 MessageBox.Show(msgtext, MyCommon.ReplaceAppName(Properties.Resources.CheckNewVersionText2), MessageBoxButtons.OK, MessageBoxIcon.Information);
6055 private void Colorize()
6059 //件数関連の場合、タイトル即時書き換え
6060 if (SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.None &&
6061 SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.Post &&
6062 SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.Ver &&
6063 SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.OwnStatus)
6065 SetMainWindowTitle();
6067 if (!StatusLabelUrl.Text.StartsWith("http")) SetStatusLabelUrl();
6068 foreach (TabPage tb in ListTab.TabPages)
6070 if (_statuses.Tabs[tb.Text].UnreadCount == 0)
6072 if (SettingDialog.TabIconDisp)
6074 if (tb.ImageIndex == 0) tb.ImageIndex = -1;
6078 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
6081 public string createDetailHtml(string orgdata)
6083 return detailHtmlFormatHeader + orgdata + detailHtmlFormatFooter;
6086 private void DisplayItemImage_Downloaded(object sender, EventArgs e)
6088 if (sender.Equals(displayItem))
6090 if (UserPicture.Image != null) UserPicture.Image.Dispose();
6092 var img = displayItem.Image;
6097 UserPicture.Image = new Bitmap(img.Image);
6101 UserPicture.Image = null;
6106 UserPicture.Image = null;
6111 private void DispSelectedPost()
6113 DispSelectedPost(false);
6116 private static PostClass displaypost = new PostClass();
6118 private void DispSelectedPost(bool forceupdate)
6120 if (_curList.SelectedIndices.Count == 0 || _curPost == null)
6123 if (!forceupdate && _curPost.Equals(displaypost))
6126 displaypost = _curPost;
6127 if (displayItem != null)
6129 displayItem.ImageDownloaded -= this.DisplayItemImage_Downloaded;
6132 displayItem = (ImageListViewItem)_curList.Items[_curList.SelectedIndices[0]];
6133 displayItem.ImageDownloaded += this.DisplayItemImage_Downloaded;
6135 string dTxt = createDetailHtml(_curPost.IsDeleted ? "(DELETED)" : _curPost.Text);
6138 SourceLinkLabel.Tag = null;
6139 SourceLinkLabel.Text = "";
6143 Match mc = Regex.Match(_curPost.SourceHtml, "<a href=\"(?<sourceurl>.+?)\"");
6146 string src = mc.Groups["sourceurl"].Value;
6147 SourceLinkLabel.Tag = mc.Groups["sourceurl"].Value;
6148 mc = Regex.Match(src, "^https?://");
6151 src = src.Insert(0, "http://twitter.com");
6153 SourceLinkLabel.Tag = src;
6157 SourceLinkLabel.Tag = null;
6159 if (string.IsNullOrEmpty(_curPost.Source))
6161 SourceLinkLabel.Text = "";
6162 //SourceLinkLabel.Visible = false;
6166 SourceLinkLabel.Text = _curPost.Source;
6167 //SourceLinkLabel.Visible = true;
6170 SourceLinkLabel.TabStop = false;
6172 if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage && !_curPost.IsOwl)
6174 NameLabel.Text = "DM TO -> ";
6176 else if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage)
6178 NameLabel.Text = "DM FROM <- ";
6182 NameLabel.Text = "";
6184 NameLabel.Text += _curPost.ScreenName + "/" + _curPost.Nickname;
6185 NameLabel.Tag = _curPost.ScreenName;
6186 if (!string.IsNullOrEmpty(_curPost.RetweetedBy))
6188 NameLabel.Text += " (RT:" + _curPost.RetweetedBy + ")";
6191 if (UserPicture.Image != null) UserPicture.Image.Dispose();
6192 UserPicture.Image = null;
6193 if (!string.IsNullOrEmpty(_curPost.ImageUrl))
6195 var image = IconCache.TryGetFromCache(_curPost.ImageUrl);
6200 UserPicture.Image = new Bitmap(image.Image);
6204 UserPicture.Image = null;
6209 NameLabel.ForeColor = System.Drawing.SystemColors.ControlText;
6210 DateTimeLabel.Text = _curPost.CreatedAt.ToString();
6211 if (_curPost.IsOwl && (SettingDialog.OneWayLove || _statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage)) NameLabel.ForeColor = _clOWL;
6212 if (_curPost.RetweetedId > 0) NameLabel.ForeColor = _clRetweet;
6213 if (_curPost.IsFav) NameLabel.ForeColor = _clFav;
6215 if (DumpPostClassToolStripMenuItem.Checked)
6217 StringBuilder sb = new StringBuilder(512);
6219 sb.Append("-----Start PostClass Dump<br>");
6220 sb.AppendFormat("TextFromApi : {0}<br>", _curPost.TextFromApi);
6221 sb.AppendFormat("(PlainText) : <xmp>{0}</xmp><br>", _curPost.TextFromApi);
6222 sb.AppendFormat("StatusId : {0}<br>", _curPost.StatusId.ToString());
6223 //sb.AppendFormat("ImageIndex : {0}<br>", _curPost.ImageIndex.ToString());
6224 sb.AppendFormat("ImageUrl : {0}<br>", _curPost.ImageUrl);
6225 sb.AppendFormat("InReplyToStatusId : {0}<br>", _curPost.InReplyToStatusId.ToString());
6226 sb.AppendFormat("InReplyToUser : {0}<br>", _curPost.InReplyToUser);
6227 sb.AppendFormat("IsDM : {0}<br>", _curPost.IsDm.ToString());
6228 sb.AppendFormat("IsFav : {0}<br>", _curPost.IsFav.ToString());
6229 sb.AppendFormat("IsMark : {0}<br>", _curPost.IsMark.ToString());
6230 sb.AppendFormat("IsMe : {0}<br>", _curPost.IsMe.ToString());
6231 sb.AppendFormat("IsOwl : {0}<br>", _curPost.IsOwl.ToString());
6232 sb.AppendFormat("IsProtect : {0}<br>", _curPost.IsProtect.ToString());
6233 sb.AppendFormat("IsRead : {0}<br>", _curPost.IsRead.ToString());
6234 sb.AppendFormat("IsReply : {0}<br>", _curPost.IsReply.ToString());
6236 foreach (string nm in _curPost.ReplyToList)
6238 sb.AppendFormat("ReplyToList : {0}<br>", nm);
6241 sb.AppendFormat("ScreenName : {0}<br>", _curPost.ScreenName);
6242 sb.AppendFormat("NickName : {0}<br>", _curPost.Nickname);
6243 sb.AppendFormat("Text : {0}<br>", _curPost.Text);
6244 sb.AppendFormat("(PlainText) : <xmp>{0}</xmp><br>", _curPost.Text);
6245 sb.AppendFormat("CreatedAt : {0}<br>", _curPost.CreatedAt.ToString());
6246 sb.AppendFormat("Source : {0}<br>", _curPost.Source);
6247 sb.AppendFormat("UserId : {0}<br>", _curPost.UserId);
6248 sb.AppendFormat("FilterHit : {0}<br>", _curPost.FilterHit);
6249 sb.AppendFormat("RetweetedBy : {0}<br>", _curPost.RetweetedBy);
6250 sb.AppendFormat("RetweetedId : {0}<br>", _curPost.RetweetedId);
6251 sb.AppendFormat("SearchTabName : {0}<br>", _curPost.RelTabName);
6252 sb.Append("-----End PostClass Dump<br>");
6254 PostBrowser.Visible = false;
6255 PostBrowser.DocumentText = detailHtmlFormatHeader + sb.ToString() + detailHtmlFormatFooter;
6256 PostBrowser.Visible = true;
6262 if (PostBrowser.DocumentText != dTxt)
6264 PostBrowser.Visible = false;
6265 PostBrowser.DocumentText = dTxt;
6267 this.SplitContainer3.Panel2Collapsed = true;
6269 if (this.IsPreviewEnable)
6270 this.tweetThumbnail1.ShowThumbnailAsync(_curPost);
6273 catch (System.Runtime.InteropServices.COMException)
6277 catch (UriFormatException)
6279 PostBrowser.DocumentText = dTxt;
6283 PostBrowser.Visible = true;
6288 private void MatomeMenuItem_Click(object sender, EventArgs e)
6290 OpenApplicationWebsite();
6293 private void OpenApplicationWebsite()
6295 OpenUriAsync(ApplicationSettings.WebsiteUrl);
6298 private void ShortcutKeyListMenuItem_Click(object sender, EventArgs e)
6300 OpenUriAsync(ApplicationSettings.ShortcutKeyUrl);
6303 private void ListTab_KeyDown(object sender, KeyEventArgs e)
6305 if (ListTab.SelectedTab != null)
6307 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.PublicSearch)
6309 Control pnl = ListTab.SelectedTab.Controls["panelSearch"];
6310 if (pnl.Controls["comboSearch"].Focused ||
6311 pnl.Controls["comboLang"].Focused ||
6312 pnl.Controls["buttonSearch"].Focused) return;
6314 ModifierState State = GetModifierState(e.Control, e.Shift, e.Alt);
6315 if (State == ModifierState.NotFlags) return;
6316 if (State != ModifierState.None) _anchorFlag = false;
6317 if (CommonKeyDown(e.KeyCode, FocusedControl.ListTab, State))
6320 e.SuppressKeyPress = true;
6325 private ModifierState GetModifierState(bool sControl, bool sShift, bool sAlt)
6327 ModifierState state = ModifierState.None;
6328 if (sControl) state = state | ModifierState.Ctrl;
6329 if (sShift) state = state | ModifierState.Shift;
6330 if (sAlt) state = state | ModifierState.Alt;
6335 private enum ModifierState
6347 //PostBrowser = 102,
6351 private enum FocusedControl : int
6359 private bool CommonKeyDown(Keys KeyCode, FocusedControl Focused, ModifierState Modifier)
6361 //リストのカーソル移動関係(上下キー、PageUp/Downに該当)
6362 if (Focused == FocusedControl.ListTab)
6364 if (Modifier == (ModifierState.Ctrl | ModifierState.Shift) ||
6365 Modifier == ModifierState.Ctrl ||
6366 Modifier == ModifierState.None ||
6367 Modifier == ModifierState.Shift)
6369 if (KeyCode == Keys.J)
6371 SendKeys.Send("{DOWN}");
6374 else if (KeyCode == Keys.K)
6376 SendKeys.Send("{UP}");
6380 if (Modifier == ModifierState.Shift ||
6381 Modifier == ModifierState.None)
6383 if (KeyCode == Keys.F)
6385 SendKeys.Send("{PGDN}");
6388 else if (KeyCode == Keys.B)
6390 SendKeys.Send("{PGUP}");
6399 case ModifierState.None:
6404 OpenApplicationWebsite();
6407 MenuItemSearchNext_Click(null, null);
6413 GetTimeline(MyCommon.WORKERTYPE.Reply, 1, 0, "");
6416 GetTimeline(MyCommon.WORKERTYPE.DirectMessegeRcv, 1, 0, "");
6419 if (Focused != FocusedControl.StatusText)
6425 case Keys.ProcessKey:
6426 if (Focused == FocusedControl.ListTab) _anchorFlag = false;
6427 JumpUnreadMenuItem_Click(null, null);
6430 if (Focused == FocusedControl.ListTab) _anchorFlag = false;
6431 ShowRelatedStatusesMenuItem_Click(null, null);
6435 if (Focused == FocusedControl.ListTab)
6448 case Keys.OemPeriod:
6452 if (this.StatusText.Enabled) this.StatusText.Focus();
6455 MakeReplyOrDirectStatus();
6462 _anchorFlag = false;
6482 // ] in_reply_to参照元へ戻る
6483 GoInReplyToPostTree();
6486 // [ in_reply_toへジャンプ
6487 GoBackInReplyToPostTree();
6490 if (ListTab.SelectedTab != null)
6492 MyCommon.TabUsageType tabtype = _statuses.Tabs[ListTab.SelectedTab.Text].TabType;
6493 if (tabtype == MyCommon.TabUsageType.Related || tabtype == MyCommon.TabUsageType.UserTimeline || tabtype == MyCommon.TabUsageType.PublicSearch)
6495 TabPage relTp = ListTab.SelectedTab;
6496 RemoveSpecifiedTab(relTp.Text, false);
6505 case ModifierState.Ctrl:
6510 MakeReplyOrDirectStatus(false, true);
6516 MakeReplyOrDirectStatus(false, false);
6519 FavoriteChange(true);
6522 doRepliedStatusOpen();
6528 ReadedStripMenuItem_Click(null, null);
6531 HashManageMenuItem_Click(null, null);
6534 UrlConvertAutoToolStripMenuItem_Click(null, null);
6537 if (Focused != FocusedControl.PostBrowser)
6539 MultiLineMenuItem_Click(null, null);
6544 MenuItemSubSearch_Click(null, null);
6551 MoveToHomeToolStripMenuItem_Click(null, null);
6555 MoveToFavToolStripMenuItem_Click(null, null);
6559 StatusOpenMenuItem_Click(null, null);
6563 OpenURLMenuItem_Click(null, null);
6567 if (Focused == FocusedControl.ListTab)
6574 return false; //スルーする
6592 // タブダイレクト選択(Ctrl+1~8,Ctrl+9)
6593 int tabNo = KeyCode - Keys.D1;
6594 if (ListTab.TabPages.Count < tabNo)
6596 ListTab.SelectedIndex = tabNo;
6597 ListTabSelect(ListTab.TabPages[tabNo]);
6600 ListTab.SelectedIndex = ListTab.TabPages.Count - 1;
6601 ListTabSelect(ListTab.TabPages[ListTab.TabPages.Count - 1]);
6605 else if (Focused == FocusedControl.StatusText)
6611 StatusText.SelectAll();
6615 if (!string.IsNullOrWhiteSpace(StatusText.Text))
6617 _history[_hisIdx] = new PostingStatus(StatusText.Text, _reply_to_id, _reply_to_name);
6619 if (KeyCode == Keys.Up)
6622 if (_hisIdx < 0) _hisIdx = 0;
6627 if (_hisIdx > _history.Count - 1) _hisIdx = _history.Count - 1;
6629 StatusText.Text = _history[_hisIdx].status;
6630 _reply_to_id = _history[_hisIdx].inReplyToId;
6631 _reply_to_name = _history[_hisIdx].inReplyToName;
6632 StatusText.SelectionStart = StatusText.Text.Length;
6636 if (ListTab.SelectedIndex == 0)
6638 ListTab.SelectedIndex = ListTab.TabCount - 1;
6642 ListTab.SelectedIndex -= 1;
6648 if (ListTab.SelectedIndex == ListTab.TabCount - 1)
6650 ListTab.SelectedIndex = 0;
6654 ListTab.SelectedIndex += 1;
6662 //フォーカスPostBrowserもしくは関係なし
6666 PostBrowser.Document.ExecCommand("SelectAll", false, null);
6670 string _selText = WebBrowser_GetSelectionText(ref PostBrowser);
6671 if (!string.IsNullOrEmpty(_selText))
6675 Clipboard.SetDataObject(_selText, false, 5, 100);
6677 catch (Exception ex)
6679 MessageBox.Show(ex.Message);
6684 MultiLineMenuItem.Checked = !MultiLineMenuItem.Checked;
6685 MultiLineMenuItem_Click(null, null);
6690 case ModifierState.Shift:
6695 MenuItemSearchPrev_Click(null, null);
6701 GetTimeline(MyCommon.WORKERTYPE.Reply, -1, 0, "");
6704 GetTimeline(MyCommon.WORKERTYPE.DirectMessegeRcv, -1, 0, "");
6708 if (Focused != FocusedControl.StatusText)
6710 if (KeyCode == Keys.R)
6717 if (Focused == FocusedControl.ListTab)
6737 GoBackInReplyToPostTree(true, false);
6740 GoBackInReplyToPostTree(true, true);
6744 // お気に入り前後ジャンプ(SHIFT+N←/P→)
6749 // お気に入り前後ジャンプ(SHIFT+N←/P→)
6753 this.GoBackSelectPostChain();
6758 case ModifierState.Alt:
6762 doReTweetOfficial(true);
6765 if (_curPost != null)
6767 doShowUserStatus(_curPost.ScreenName, false);
6772 ScrollDownPostBrowser(false);
6775 ScrollDownPostBrowser(true);
6778 PageDownPostBrowser(false);
6781 PageDownPostBrowser(true);
6784 if (Focused == FocusedControl.ListTab)
6786 // 別タブの同じ書き込みへ(ALT+←/→)
6787 if (KeyCode == Keys.Right)
6789 GoSamePostToAnotherTab(false);
6792 else if (KeyCode == Keys.Left)
6794 GoSamePostToAnotherTab(true);
6799 case ModifierState.Ctrl | ModifierState.Shift:
6803 MakeReplyOrDirectStatus(false, true, true);
6809 if (ListTab.SelectedTab != null)
6811 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.PublicSearch)
6813 ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"].Focus();
6819 FavoriteChange(false);
6822 UnreadStripMenuItem_Click(null, null);
6825 HashToggleMenuItem_Click(null, null);
6828 ImageSelectMenuItem_Click(null, null);
6834 FavorareMenuItem_Click(null, null);
6837 if (Focused == FocusedControl.StatusText)
6843 if (_curList != null && _curList.Items.Count != 0 &&
6844 _curList.SelectedIndices.Count > 0 && _curList.SelectedIndices[0] > 0)
6846 idx = _curList.SelectedIndices[0] - 1;
6847 SelectListItem(_curList, idx);
6848 _curList.EnsureVisible(idx);
6853 if (_curList != null && _curList.Items.Count != 0 && _curList.SelectedIndices.Count > 0
6854 && _curList.SelectedIndices[0] < _curList.Items.Count - 1)
6856 idx = _curList.SelectedIndices[0] + 1;
6857 SelectListItem(_curList, idx);
6858 _curList.EnsureVisible(idx);
6863 if (StatusText.SelectionStart > 0)
6865 int endidx = StatusText.SelectionStart - 1;
6866 string startstr = "";
6867 bool pressed = false;
6868 for (int i = StatusText.SelectionStart - 1; i >= 0; i--)
6870 char c = StatusText.Text[i];
6871 if (Char.IsLetterOrDigit(c) || c == '_')
6878 startstr = StatusText.Text.Substring(i + 1, endidx - i);
6879 int cnt = AtIdSupl.ItemCount;
6880 ShowSuplDialog(StatusText, AtIdSupl, startstr.Length + 1, startstr);
6881 if (AtIdSupl.ItemCount != cnt) _modifySettingAtId = true;
6886 startstr = StatusText.Text.Substring(i + 1, endidx - i);
6887 ShowSuplDialog(StatusText, HashSupl, startstr.Length + 1, startstr);
6899 else if (Focused == FocusedControl.ListTab)
6901 DetailsListView lst = (DetailsListView)ListTab.SelectedTab.Tag;
6913 // ソートダイレクト選択(Ctrl+Shift+1~8,Ctrl+Shift+9)
6914 int colNo = KeyCode - Keys.D1;
6915 if (lst.Columns.Count < colNo) return false;
6916 col = lst.Columns.Cast<ColumnHeader>().Where((x) => { return x.DisplayIndex == colNo; }).FirstOrDefault();
6917 if (col == null) return false;
6918 MyList_ColumnClick(lst, new ColumnClickEventArgs(col.Index));
6921 col = lst.Columns.Cast<ColumnHeader>().OrderByDescending((x) => { return x.DisplayIndex; }).First();
6922 MyList_ColumnClick(lst, new ColumnClickEventArgs(col.Index));
6927 case ModifierState.Ctrl | ModifierState.Alt:
6928 if (KeyCode == Keys.S)
6930 FavoritesRetweetOriginal();
6933 else if (KeyCode == Keys.R)
6935 FavoritesRetweetUnofficial();
6938 else if (KeyCode == Keys.H)
6940 OpenUserAppointUrl();
6944 case ModifierState.Alt | ModifierState.Shift:
6945 if (Focused == FocusedControl.PostBrowser)
6947 if (KeyCode == Keys.R)
6948 doReTweetUnofficial();
6949 else if (KeyCode == Keys.C)
6956 if (!this.ExistCurrentPost) return false;
6957 doTranslation(_curPost.TextFromApi);
6960 doReTweetUnofficial();
6966 this.tweetThumbnail1.ScrollUp();
6969 this.tweetThumbnail1.ScrollDown();
6972 if (Focused == FocusedControl.ListTab && KeyCode == Keys.Enter)
6974 if (!this.SplitContainer3.Panel2Collapsed)
6976 OpenThumbnailPicture(this.tweetThumbnail1.Thumbnail);
6986 private void ScrollDownPostBrowser(bool forward)
6988 HtmlDocument doc = PostBrowser.Document;
6989 if (doc == null) return;
6990 if (doc.Body == null) return;
6993 doc.Body.ScrollTop += SettingDialog.FontDetail.Height;
6995 doc.Body.ScrollTop -= SettingDialog.FontDetail.Height;
6998 private void PageDownPostBrowser(bool forward)
7000 HtmlDocument doc = PostBrowser.Document;
7001 if (doc == null) return;
7002 if (doc.Body == null) return;
7005 doc.Body.ScrollTop += PostBrowser.ClientRectangle.Height - SettingDialog.FontDetail.Height;
7007 doc.Body.ScrollTop -= PostBrowser.ClientRectangle.Height - SettingDialog.FontDetail.Height;
7010 private void GoNextTab(bool forward)
7012 int idx = ListTab.SelectedIndex;
7016 if (idx > ListTab.TabPages.Count - 1) idx = 0;
7021 if (idx < 0) idx = ListTab.TabPages.Count - 1;
7023 ListTab.SelectedIndex = idx;
7024 ListTabSelect(ListTab.TabPages[idx]);
7027 private void CopyStot()
7030 StringBuilder sb = new StringBuilder();
7031 bool IsProtected = false;
7033 if (this._curTab != null && this._statuses.GetTabByName(this._curTab.Text) != null) isDm = this._statuses.GetTabByName(this._curTab.Text).TabType == MyCommon.TabUsageType.DirectMessage;
7034 foreach (int idx in _curList.SelectedIndices)
7036 PostClass post = _statuses[_curTab.Text, idx];
7042 if (post.IsDeleted) continue;
7045 if (post.RetweetedId > 0)
7046 sb.AppendFormat("{0}:{1} [http://twitter.com/{0}/status/{2}]{3}", post.ScreenName, post.TextSingleLine, post.RetweetedId, Environment.NewLine);
7048 sb.AppendFormat("{0}:{1} [http://twitter.com/{0}/status/{2}]{3}", post.ScreenName, post.TextSingleLine, post.StatusId, Environment.NewLine);
7052 sb.AppendFormat("{0}:{1} [{2}]{3}", post.ScreenName, post.TextSingleLine, post.StatusId, Environment.NewLine);
7057 MessageBox.Show(Properties.Resources.CopyStotText1);
7061 clstr = sb.ToString();
7064 Clipboard.SetDataObject(clstr, false, 5, 100);
7066 catch (Exception ex)
7068 MessageBox.Show(ex.Message);
7073 private void CopyIdUri()
7076 StringBuilder sb = new StringBuilder();
7077 if (this._curTab == null) return;
7078 if (this._statuses.GetTabByName(this._curTab.Text) == null) return;
7079 if (this._statuses.GetTabByName(this._curTab.Text).TabType == MyCommon.TabUsageType.DirectMessage) return;
7080 foreach (int idx in _curList.SelectedIndices)
7082 var post = _statuses[_curTab.Text, idx];
7083 sb.Append(MyCommon.GetStatusUrl(post));
7087 clstr = sb.ToString();
7090 Clipboard.SetDataObject(clstr, false, 5, 100);
7092 catch (Exception ex)
7094 MessageBox.Show(ex.Message);
7099 private void GoFav(bool forward)
7101 if (_curList.VirtualListSize == 0) return;
7108 if (_curList.SelectedIndices.Count == 0)
7114 fIdx = _curList.SelectedIndices[0] + 1;
7115 if (fIdx > _curList.VirtualListSize - 1) return;
7117 toIdx = _curList.VirtualListSize;
7122 if (_curList.SelectedIndices.Count == 0)
7124 fIdx = _curList.VirtualListSize - 1;
7128 fIdx = _curList.SelectedIndices[0] - 1;
7129 if (fIdx < 0) return;
7135 for (int idx = fIdx; idx != toIdx; idx += stp)
7137 if (_statuses[_curTab.Text, idx].IsFav)
7139 SelectListItem(_curList, idx);
7140 _curList.EnsureVisible(idx);
7146 private void GoSamePostToAnotherTab(bool left)
7148 if (_curList.VirtualListSize == 0) return;
7154 if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage) return; // Directタブは対象外(見つかるはずがない)
7155 if (_curList.SelectedIndices.Count == 0) return; //未選択も処理しない
7157 targetId = GetCurTabPost(_curList.SelectedIndices[0]).StatusId;
7162 if (ListTab.SelectedIndex == 0)
7168 fIdx = ListTab.SelectedIndex - 1;
7176 if (ListTab.SelectedIndex == ListTab.TabCount - 1)
7182 fIdx = ListTab.SelectedIndex + 1;
7184 toIdx = ListTab.TabCount;
7189 for (int tabidx = fIdx; tabidx != toIdx; tabidx += stp)
7191 if (_statuses.Tabs[ListTab.TabPages[tabidx].Text].TabType == MyCommon.TabUsageType.DirectMessage) continue; // Directタブは対象外
7192 for (int idx = 0; idx < ((DetailsListView)ListTab.TabPages[tabidx].Tag).VirtualListSize; idx++)
7194 if (_statuses[ListTab.TabPages[tabidx].Text, idx].StatusId == targetId)
7196 ListTab.SelectedIndex = tabidx;
7197 ListTabSelect(ListTab.TabPages[tabidx]);
7198 SelectListItem(_curList, idx);
7199 _curList.EnsureVisible(idx);
7208 private void GoPost(bool forward)
7210 if (_curList.SelectedIndices.Count == 0 || _curPost == null) return;
7217 fIdx = _curList.SelectedIndices[0] + 1;
7218 if (fIdx > _curList.VirtualListSize - 1) return;
7219 toIdx = _curList.VirtualListSize;
7224 fIdx = _curList.SelectedIndices[0] - 1;
7225 if (fIdx < 0) return;
7231 if (_curPost.RetweetedId == 0)
7233 name = _curPost.ScreenName;
7237 name = _curPost.RetweetedBy;
7239 for (int idx = fIdx; idx != toIdx; idx += stp)
7241 if (_statuses[_curTab.Text, idx].RetweetedId == 0)
7243 if (_statuses[_curTab.Text, idx].ScreenName == name)
7245 SelectListItem(_curList, idx);
7246 _curList.EnsureVisible(idx);
7252 if (_statuses[_curTab.Text, idx].RetweetedBy == name)
7254 SelectListItem(_curList, idx);
7255 _curList.EnsureVisible(idx);
7262 private void GoRelPost(bool forward)
7264 if (_curList.SelectedIndices.Count == 0) return;
7271 fIdx = _curList.SelectedIndices[0] + 1;
7272 if (fIdx > _curList.VirtualListSize - 1) return;
7273 toIdx = _curList.VirtualListSize;
7278 fIdx = _curList.SelectedIndices[0] - 1;
7279 if (fIdx < 0) return;
7286 if (_curPost == null) return;
7287 _anchorPost = _curPost;
7292 if (_anchorPost == null) return;
7295 for (int idx = fIdx; idx != toIdx; idx += stp)
7297 PostClass post = _statuses[_curTab.Text, idx];
7298 if (post.ScreenName == _anchorPost.ScreenName ||
7299 post.RetweetedBy == _anchorPost.ScreenName ||
7300 post.ScreenName == _anchorPost.RetweetedBy ||
7301 (!string.IsNullOrEmpty(post.RetweetedBy) && post.RetweetedBy == _anchorPost.RetweetedBy) ||
7302 _anchorPost.ReplyToList.Contains(post.ScreenName.ToLower()) ||
7303 _anchorPost.ReplyToList.Contains(post.RetweetedBy.ToLower()) ||
7304 post.ReplyToList.Contains(_anchorPost.ScreenName.ToLower()) ||
7305 post.ReplyToList.Contains(_anchorPost.RetweetedBy.ToLower()))
7307 SelectListItem(_curList, idx);
7308 _curList.EnsureVisible(idx);
7314 private void GoAnchor()
7316 if (_anchorPost == null) return;
7317 int idx = _statuses.Tabs[_curTab.Text].IndexOf(_anchorPost.StatusId);
7318 if (idx == -1) return;
7320 SelectListItem(_curList, idx);
7321 _curList.EnsureVisible(idx);
7324 private void GoTopEnd(bool GoTop)
7331 _item = _curList.GetItemAt(0, 25);
7339 _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1);
7341 idx = _curList.VirtualListSize - 1;
7345 SelectListItem(_curList, idx);
7348 private void GoMiddle()
7355 _item = _curList.GetItemAt(0, 0);
7365 _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1);
7368 idx2 = _curList.VirtualListSize - 1;
7374 idx3 = (idx1 + idx2) / 2;
7376 SelectListItem(_curList, idx3);
7379 private void GoLast()
7381 if (_curList.VirtualListSize == 0) return;
7383 if (_statuses.SortOrder == SortOrder.Ascending)
7385 SelectListItem(_curList, _curList.VirtualListSize - 1);
7386 _curList.EnsureVisible(_curList.VirtualListSize - 1);
7390 SelectListItem(_curList, 0);
7391 _curList.EnsureVisible(0);
7395 private void MoveTop()
7397 if (_curList.SelectedIndices.Count == 0) return;
7398 int idx = _curList.SelectedIndices[0];
7399 if (_statuses.SortOrder == SortOrder.Ascending)
7401 _curList.EnsureVisible(_curList.VirtualListSize - 1);
7405 _curList.EnsureVisible(0);
7407 _curList.EnsureVisible(idx);
7410 private void GoInReplyToPostTree()
7412 if (_curPost == null) return;
7414 TabClass curTabClass = _statuses.Tabs[_curTab.Text];
7416 if (curTabClass.TabType == MyCommon.TabUsageType.PublicSearch && _curPost.InReplyToStatusId == 0 && _curPost.TextFromApi.Contains("@"))
7418 PostClass post = null;
7419 string r = tw.GetStatusApi(false, _curPost.StatusId, ref post);
7420 if (string.IsNullOrEmpty(r) && post != null)
7422 _curPost.InReplyToStatusId = post.InReplyToStatusId;
7423 _curPost.InReplyToUser = post.InReplyToUser;
7424 _curPost.IsReply = post.IsReply;
7425 this.PurgeListViewItemCache();
7426 _curList.RedrawItems(_curItemIndex, _curItemIndex, false);
7430 this.StatusLabel.Text = r;
7434 if (!(this.ExistCurrentPost && _curPost.InReplyToUser != null && _curPost.InReplyToStatusId > 0)) return;
7436 if (replyChains == null || (replyChains.Count > 0 && replyChains.Peek().InReplyToId != _curPost.StatusId))
7438 replyChains = new Stack<ReplyChain>();
7440 replyChains.Push(new ReplyChain(_curPost.StatusId, _curPost.InReplyToStatusId, _curTab));
7443 string inReplyToTabName;
7444 long inReplyToId = _curPost.InReplyToStatusId;
7445 string inReplyToUser = _curPost.InReplyToUser;
7446 Dictionary<long, PostClass> curTabPosts;
7448 if (_statuses.Tabs[_curTab.Text].IsInnerStorageTabType)
7449 curTabPosts = curTabClass.Posts;
7451 curTabPosts = _statuses.Posts;
7453 var inReplyToPosts = from tab in _statuses.Tabs.Values
7454 orderby tab != curTabClass
7455 from post in ((Dictionary<long, PostClass>)(tab.IsInnerStorageTabType ? tab.Posts : _statuses.Posts)).Values
7456 where post.StatusId == inReplyToId
7457 let index = tab.IndexOf(post.StatusId)
7459 select new {Tab = tab, Index = index};
7463 var inReplyPost = inReplyToPosts.First();
7464 inReplyToTabName = inReplyPost.Tab.TabName;
7465 inReplyToIndex = inReplyPost.Index;
7467 catch (InvalidOperationException)
7469 PostClass post = null;
7470 string r = tw.GetStatusApi(false, _curPost.InReplyToStatusId, ref post);
7471 if (string.IsNullOrEmpty(r) && post != null)
7474 _statuses.AddPost(post);
7475 _statuses.DistributePosts();
7476 //_statuses.SubmitUpdate(null, null, null, false);
7477 this.RefreshTimeline(false);
7480 var inReplyPost = inReplyToPosts.First();
7481 inReplyToTabName = inReplyPost.Tab.TabName;
7482 inReplyToIndex = inReplyPost.Index;
7484 catch (InvalidOperationException)
7486 OpenUriAsync("http://twitter.com/" + inReplyToUser + "/statuses/" + inReplyToId.ToString());
7492 this.StatusLabel.Text = r;
7493 OpenUriAsync("http://twitter.com/" + inReplyToUser + "/statuses/" + inReplyToId.ToString());
7498 TabPage tabPage = this.ListTab.TabPages.Cast<TabPage>().First((tp) => { return tp.Text == inReplyToTabName; });
7499 DetailsListView listView = (DetailsListView)tabPage.Tag;
7501 if (_curTab != tabPage)
7503 this.ListTab.SelectTab(tabPage);
7506 this.SelectListItem(listView, inReplyToIndex);
7507 listView.EnsureVisible(inReplyToIndex);
7510 private void GoBackInReplyToPostTree(bool parallel = false, bool isForward = true)
7512 if (_curPost == null) return;
7514 TabClass curTabClass = _statuses.Tabs[_curTab.Text];
7515 Dictionary<long, PostClass> curTabPosts = curTabClass.IsInnerStorageTabType ? curTabClass.Posts : _statuses.Posts;
7519 if (_curPost.InReplyToStatusId != 0)
7521 var posts = from t in _statuses.Tabs
7522 from p in t.Value.IsInnerStorageTabType ? t.Value.Posts : _statuses.Posts
7523 where p.Value.StatusId != _curPost.StatusId && p.Value.InReplyToStatusId == _curPost.InReplyToStatusId
7524 let indexOf = t.Value.IndexOf(p.Value.StatusId)
7526 orderby isForward ? indexOf : indexOf * -1
7527 orderby t.Value != curTabClass
7528 select new {Tab = t.Value, Post = p.Value, Index = indexOf};
7531 var postList = posts.ToList();
7532 for (int i = postList.Count - 1; i >= 0; i--)
7535 if (postList.FindIndex((pst) => { return pst.Post.StatusId == postList[index].Post.StatusId; }) != index)
7537 postList.RemoveAt(index);
7540 var post = postList.FirstOrDefault((pst) => { return pst.Tab == curTabClass && isForward ? pst.Index > _curItemIndex : pst.Index < _curItemIndex; });
7541 if (post == null) post = postList.FirstOrDefault((pst) => { return pst.Tab != curTabClass; });
7542 if (post == null) post = postList.First();
7543 this.ListTab.SelectTab(this.ListTab.TabPages.Cast<TabPage>().First((tp) => { return tp.Text == post.Tab.TabName; }));
7544 DetailsListView listView = (DetailsListView)this.ListTab.SelectedTab.Tag;
7545 SelectListItem(listView, post.Index);
7546 listView.EnsureVisible(post.Index);
7548 catch (InvalidOperationException)
7556 if (replyChains == null || replyChains.Count < 1)
7558 var posts = from t in _statuses.Tabs
7559 from p in t.Value.IsInnerStorageTabType ? t.Value.Posts : _statuses.Posts
7560 where p.Value.InReplyToStatusId == _curPost.StatusId
7561 let indexOf = t.Value.IndexOf(p.Value.StatusId)
7564 orderby t.Value != curTabClass
7565 select new {Tab = t.Value, Index = indexOf};
7568 var post = posts.First();
7569 this.ListTab.SelectTab(this.ListTab.TabPages.Cast<TabPage>().First((tp) => { return tp.Text == post.Tab.TabName; }));
7570 DetailsListView listView = (DetailsListView)this.ListTab.SelectedTab.Tag;
7571 SelectListItem(listView, post.Index);
7572 listView.EnsureVisible(post.Index);
7574 catch (InvalidOperationException)
7581 ReplyChain chainHead = replyChains.Pop();
7582 if (chainHead.InReplyToId == _curPost.StatusId)
7584 int idx = _statuses.Tabs[chainHead.OriginalTab.Text].IndexOf(chainHead.OriginalId);
7593 ListTab.SelectTab(chainHead.OriginalTab);
7599 SelectListItem(_curList, idx);
7600 _curList.EnsureVisible(idx);
7606 this.GoBackInReplyToPostTree(parallel);
7612 private void GoBackSelectPostChain()
7616 this.selectPostChains.Pop();
7617 Tuple<TabPage, PostClass> tabPostPair = this.selectPostChains.Pop();
7618 if (!this.ListTab.TabPages.Contains(tabPostPair.Item1)) return;
7619 this.ListTab.SelectedTab = tabPostPair.Item1;
7620 if (tabPostPair.Item2 != null && this._statuses.Tabs[this._curTab.Text].IndexOf(tabPostPair.Item2.StatusId) > -1)
7622 this.SelectListItem(this._curList, this._statuses.Tabs[this._curTab.Text].IndexOf(tabPostPair.Item2.StatusId));
7623 this._curList.EnsureVisible(this._statuses.Tabs[this._curTab.Text].IndexOf(tabPostPair.Item2.StatusId));
7626 catch (InvalidOperationException)
7631 private void PushSelectPostChain()
7633 if (this.selectPostChains.Count == 0 || (this.selectPostChains.Peek().Item1.Text != this._curTab.Text || this._curPost != this.selectPostChains.Peek().Item2))
7635 this.selectPostChains.Push(Tuple.Create(this._curTab, _curPost));
7639 private void TrimPostChain()
7641 if (this.selectPostChains.Count < 2000) return;
7642 Stack<Tuple<TabPage, PostClass>> p = new Stack<Tuple<TabPage, PostClass>>();
7643 for (int i = 0; i < 2000; i++)
7645 p.Push(this.selectPostChains.Pop());
7647 this.selectPostChains.Clear();
7648 for (int i = 0; i < 2000; i++)
7650 this.selectPostChains.Push(p.Pop());
7654 private bool GoStatus(long statusId)
7656 if (statusId == 0) return false;
7657 for (int tabidx = 0; tabidx < ListTab.TabCount; tabidx++)
7659 if (_statuses.Tabs[ListTab.TabPages[tabidx].Text].TabType != MyCommon.TabUsageType.DirectMessage && _statuses.Tabs[ListTab.TabPages[tabidx].Text].Contains(statusId))
7661 int idx = _statuses.Tabs[ListTab.TabPages[tabidx].Text].IndexOf(statusId);
7662 ListTab.SelectedIndex = tabidx;
7663 ListTabSelect(ListTab.TabPages[tabidx]);
7664 SelectListItem(_curList, idx);
7665 _curList.EnsureVisible(idx);
7672 private bool GoDirectMessage(long statusId)
7674 if (statusId == 0) return false;
7675 for (int tabidx = 0; tabidx < ListTab.TabCount; tabidx++)
7677 if (_statuses.Tabs[ListTab.TabPages[tabidx].Text].TabType == MyCommon.TabUsageType.DirectMessage && _statuses.Tabs[ListTab.TabPages[tabidx].Text].Contains(statusId))
7679 int idx = _statuses.Tabs[ListTab.TabPages[tabidx].Text].IndexOf(statusId);
7680 ListTab.SelectedIndex = tabidx;
7681 ListTabSelect(ListTab.TabPages[tabidx]);
7682 SelectListItem(_curList, idx);
7683 _curList.EnsureVisible(idx);
7690 private void MyList_MouseClick(object sender, MouseEventArgs e)
7692 _anchorFlag = false;
7695 private void StatusText_Enter(object sender, EventArgs e)
7697 // フォーカスの戻り先を StatusText に設定
7698 this.Tag = StatusText;
7699 StatusText.BackColor = _clInputBackcolor;
7702 public Color InputBackColor
7704 get { return _clInputBackcolor; }
7705 set { _clInputBackcolor = value; }
7708 private void StatusText_Leave(object sender, EventArgs e)
7710 // フォーカスがメニューに遷移しないならばフォーカスはタブに移ることを期待
7711 if (ListTab.SelectedTab != null && MenuStrip1.Tag == null) this.Tag = ListTab.SelectedTab.Tag;
7712 StatusText.BackColor = Color.FromKnownColor(KnownColor.Window);
7715 private void StatusText_KeyDown(object sender, KeyEventArgs e)
7717 ModifierState State = GetModifierState(e.Control, e.Shift, e.Alt);
7718 if (State == ModifierState.NotFlags) return;
7719 if (CommonKeyDown(e.KeyCode, FocusedControl.StatusText, State))
7722 e.SuppressKeyPress = true;
7725 this.StatusText_TextChanged(null, null);
7728 private void SaveConfigsAll(bool ifModified)
7732 SaveConfigsCommon();
7739 if (_modifySettingCommon) SaveConfigsCommon();
7740 if (_modifySettingLocal) SaveConfigsLocal();
7741 if (_modifySettingAtId) SaveConfigsAtId();
7745 private void SaveConfigsAtId()
7747 if (_ignoreConfigSave || !SettingDialog.UseAtIdSupplement && AtIdSupl == null) return;
7749 _modifySettingAtId = false;
7750 SettingAtIdList cfgAtId = new SettingAtIdList(AtIdSupl.GetItemList());
7754 private void SaveConfigsCommon()
7756 if (_ignoreConfigSave) return;
7758 _modifySettingCommon = false;
7761 _cfgCommon.UserName = tw.Username;
7762 _cfgCommon.UserId = tw.UserId;
7763 _cfgCommon.Password = tw.Password;
7764 _cfgCommon.Token = tw.AccessToken;
7765 _cfgCommon.TokenSecret = tw.AccessTokenSecret;
7766 _cfgCommon.UserAccounts = SettingDialog.UserAccounts;
7767 _cfgCommon.UserstreamStartup = SettingDialog.UserstreamStartup;
7768 _cfgCommon.UserstreamPeriod = SettingDialog.UserstreamPeriodInt;
7769 _cfgCommon.TimelinePeriod = SettingDialog.TimelinePeriodInt;
7770 _cfgCommon.ReplyPeriod = SettingDialog.ReplyPeriodInt;
7771 _cfgCommon.DMPeriod = SettingDialog.DMPeriodInt;
7772 _cfgCommon.PubSearchPeriod = SettingDialog.PubSearchPeriodInt;
7773 _cfgCommon.ListsPeriod = SettingDialog.ListsPeriodInt;
7774 _cfgCommon.UserTimelinePeriod = SettingDialog.UserTimelinePeriodInt;
7775 _cfgCommon.Read = SettingDialog.Readed;
7776 _cfgCommon.IconSize = SettingDialog.IconSz;
7777 _cfgCommon.UnreadManage = SettingDialog.UnreadManage;
7778 _cfgCommon.PlaySound = SettingDialog.PlaySound;
7779 _cfgCommon.OneWayLove = SettingDialog.OneWayLove;
7781 _cfgCommon.NameBalloon = SettingDialog.NameBalloon;
7782 _cfgCommon.PostCtrlEnter = SettingDialog.PostCtrlEnter;
7783 _cfgCommon.PostShiftEnter = SettingDialog.PostShiftEnter;
7784 _cfgCommon.CountApi = SettingDialog.CountApi;
7785 _cfgCommon.CountApiReply = SettingDialog.CountApiReply;
7786 _cfgCommon.PostAndGet = SettingDialog.PostAndGet;
7787 _cfgCommon.DispUsername = SettingDialog.DispUsername;
7788 _cfgCommon.MinimizeToTray = SettingDialog.MinimizeToTray;
7789 _cfgCommon.CloseToExit = SettingDialog.CloseToExit;
7790 _cfgCommon.DispLatestPost = SettingDialog.DispLatestPost;
7791 _cfgCommon.SortOrderLock = SettingDialog.SortOrderLock;
7792 _cfgCommon.ViewTabBottom = SettingDialog.ViewTabBottom;
7793 _cfgCommon.TinyUrlResolve = SettingDialog.TinyUrlResolve;
7794 _cfgCommon.ShortUrlForceResolve = SettingDialog.ShortUrlForceResolve;
7795 _cfgCommon.PeriodAdjust = SettingDialog.PeriodAdjust;
7796 _cfgCommon.StartupVersion = SettingDialog.StartupVersion;
7797 _cfgCommon.StartupFollowers = SettingDialog.StartupFollowers;
7798 _cfgCommon.RestrictFavCheck = SettingDialog.RestrictFavCheck;
7799 _cfgCommon.AlwaysTop = SettingDialog.AlwaysTop;
7800 _cfgCommon.UrlConvertAuto = SettingDialog.UrlConvertAuto;
7801 _cfgCommon.Outputz = SettingDialog.OutputzEnabled;
7802 _cfgCommon.OutputzKey = SettingDialog.OutputzKey;
7803 _cfgCommon.OutputzUrlMode = SettingDialog.OutputzUrlmode;
7804 _cfgCommon.UseUnreadStyle = SettingDialog.UseUnreadStyle;
7805 _cfgCommon.DateTimeFormat = SettingDialog.DateTimeFormat;
7806 _cfgCommon.DefaultTimeOut = SettingDialog.DefaultTimeOut;
7807 _cfgCommon.RetweetNoConfirm = SettingDialog.RetweetNoConfirm;
7808 _cfgCommon.LimitBalloon = SettingDialog.LimitBalloon;
7809 _cfgCommon.EventNotifyEnabled = SettingDialog.EventNotifyEnabled;
7810 _cfgCommon.EventNotifyFlag = SettingDialog.EventNotifyFlag;
7811 _cfgCommon.IsMyEventNotifyFlag = SettingDialog.IsMyEventNotifyFlag;
7812 _cfgCommon.ForceEventNotify = SettingDialog.ForceEventNotify;
7813 _cfgCommon.FavEventUnread = SettingDialog.FavEventUnread;
7814 _cfgCommon.TranslateLanguage = SettingDialog.TranslateLanguage;
7815 _cfgCommon.EventSoundFile = SettingDialog.EventSoundFile;
7816 _cfgCommon.AutoShortUrlFirst = SettingDialog.AutoShortUrlFirst;
7817 _cfgCommon.TabIconDisp = SettingDialog.TabIconDisp;
7818 _cfgCommon.ReplyIconState = SettingDialog.ReplyIconState;
7819 _cfgCommon.ReadOwnPost = SettingDialog.ReadOwnPost;
7820 _cfgCommon.GetFav = SettingDialog.GetFav;
7821 _cfgCommon.IsMonospace = SettingDialog.IsMonospace;
7822 if (IdeographicSpaceToSpaceToolStripMenuItem != null &&
7823 IdeographicSpaceToSpaceToolStripMenuItem.IsDisposed == false)
7825 _cfgCommon.WideSpaceConvert = this.IdeographicSpaceToSpaceToolStripMenuItem.Checked;
7827 _cfgCommon.ReadOldPosts = SettingDialog.ReadOldPosts;
7828 _cfgCommon.UseSsl = SettingDialog.UseSsl;
7829 _cfgCommon.BilyUser = SettingDialog.BitlyUser;
7830 _cfgCommon.BitlyPwd = SettingDialog.BitlyPwd;
7831 _cfgCommon.ShowGrid = SettingDialog.ShowGrid;
7832 _cfgCommon.UseAtIdSupplement = SettingDialog.UseAtIdSupplement;
7833 _cfgCommon.UseHashSupplement = SettingDialog.UseHashSupplement;
7834 _cfgCommon.PreviewEnable = SettingDialog.PreviewEnable;
7835 _cfgCommon.Language = SettingDialog.Language;
7837 _cfgCommon.SortOrder = (int)_statuses.SortOrder;
7838 switch (_statuses.SortMode)
7840 case IdComparerClass.ComparerMode.Nickname: //ニックネーム
7841 _cfgCommon.SortColumn = 1;
7843 case IdComparerClass.ComparerMode.Data: //本文
7844 _cfgCommon.SortColumn = 2;
7846 case IdComparerClass.ComparerMode.Id: //時刻=発言Id
7847 _cfgCommon.SortColumn = 3;
7849 case IdComparerClass.ComparerMode.Name: //名前
7850 _cfgCommon.SortColumn = 4;
7852 case IdComparerClass.ComparerMode.Source: //Source
7853 _cfgCommon.SortColumn = 7;
7857 _cfgCommon.Nicoms = SettingDialog.Nicoms;
7858 _cfgCommon.HashTags = HashMgr.HashHistories;
7859 if (HashMgr.IsPermanent)
7861 _cfgCommon.HashSelected = HashMgr.UseHash;
7865 _cfgCommon.HashSelected = "";
7867 _cfgCommon.HashIsHead = HashMgr.IsHead;
7868 _cfgCommon.HashIsPermanent = HashMgr.IsPermanent;
7869 _cfgCommon.HashIsNotAddToAtReply = HashMgr.IsNotAddToAtReply;
7870 _cfgCommon.TwitterUrl = SettingDialog.TwitterApiUrl;
7871 _cfgCommon.TwitterSearchUrl = SettingDialog.TwitterSearchApiUrl;
7872 _cfgCommon.HotkeyEnabled = SettingDialog.HotkeyEnabled;
7873 _cfgCommon.HotkeyModifier = SettingDialog.HotkeyMod;
7874 _cfgCommon.HotkeyKey = SettingDialog.HotkeyKey;
7875 _cfgCommon.HotkeyValue = SettingDialog.HotkeyValue;
7876 _cfgCommon.BlinkNewMentions = SettingDialog.BlinkNewMentions;
7877 if (ToolStripFocusLockMenuItem != null &&
7878 ToolStripFocusLockMenuItem.IsDisposed == false)
7880 _cfgCommon.FocusLockToStatusText = this.ToolStripFocusLockMenuItem.Checked;
7882 _cfgCommon.UseAdditionalCount = SettingDialog.UseAdditionalCount;
7883 _cfgCommon.MoreCountApi = SettingDialog.MoreCountApi;
7884 _cfgCommon.FirstCountApi = SettingDialog.FirstCountApi;
7885 _cfgCommon.SearchCountApi = SettingDialog.SearchCountApi;
7886 _cfgCommon.FavoritesCountApi = SettingDialog.FavoritesCountApi;
7887 _cfgCommon.UserTimelineCountApi = SettingDialog.UserTimelineCountApi;
7888 _cfgCommon.TrackWord = tw.TrackWord;
7889 _cfgCommon.AllAtReply = tw.AllAtReply;
7890 _cfgCommon.OpenUserTimeline = SettingDialog.OpenUserTimeline;
7891 _cfgCommon.ListCountApi = SettingDialog.ListCountApi;
7892 _cfgCommon.UseImageService = ImageServiceCombo.SelectedIndex;
7893 _cfgCommon.ListDoubleClickAction = SettingDialog.ListDoubleClickAction;
7894 _cfgCommon.UserAppointUrl = SettingDialog.UserAppointUrl;
7895 _cfgCommon.HideDuplicatedRetweets = SettingDialog.HideDuplicatedRetweets;
7896 _cfgCommon.IsPreviewFoursquare = SettingDialog.IsPreviewFoursquare;
7897 _cfgCommon.MapThumbnailProvider = SettingDialog.MapThumbnailProvider;
7898 _cfgCommon.MapThumbnailHeight = SettingDialog.MapThumbnailHeight;
7899 _cfgCommon.MapThumbnailWidth = SettingDialog.MapThumbnailWidth;
7900 _cfgCommon.MapThumbnailZoom = SettingDialog.MapThumbnailZoom;
7901 _cfgCommon.IsListsIncludeRts = SettingDialog.IsListStatusesIncludeRts;
7902 _cfgCommon.TabMouseLock = SettingDialog.TabMouseLock;
7903 _cfgCommon.IsRemoveSameEvent = SettingDialog.IsRemoveSameEvent;
7904 _cfgCommon.IsUseNotifyGrowl = SettingDialog.IsNotifyUseGrowl;
7910 private void SaveConfigsLocal()
7912 if (_ignoreConfigSave) return;
7915 _modifySettingLocal = false;
7916 _cfgLocal.FormSize = _mySize;
7917 _cfgLocal.FormLocation = _myLoc;
7918 _cfgLocal.SplitterDistance = _mySpDis;
7919 _cfgLocal.PreviewDistance = _mySpDis3;
7920 _cfgLocal.StatusMultiline = StatusText.Multiline;
7921 _cfgLocal.StatusTextHeight = _mySpDis2;
7922 _cfgLocal.AdSplitterDistance = _myAdSpDis;
7923 _cfgLocal.StatusText = SettingDialog.Status;
7925 _cfgLocal.FontUnread = _fntUnread;
7926 _cfgLocal.ColorUnread = _clUnread;
7927 _cfgLocal.FontRead = _fntReaded;
7928 _cfgLocal.ColorRead = _clReaded;
7929 _cfgLocal.FontDetail = _fntDetail;
7930 _cfgLocal.ColorDetail = _clDetail;
7931 _cfgLocal.ColorDetailBackcolor = _clDetailBackcolor;
7932 _cfgLocal.ColorDetailLink = _clDetailLink;
7933 _cfgLocal.ColorFav = _clFav;
7934 _cfgLocal.ColorOWL = _clOWL;
7935 _cfgLocal.ColorRetweet = _clRetweet;
7936 _cfgLocal.ColorSelf = _clSelf;
7937 _cfgLocal.ColorAtSelf = _clAtSelf;
7938 _cfgLocal.ColorTarget = _clTarget;
7939 _cfgLocal.ColorAtTarget = _clAtTarget;
7940 _cfgLocal.ColorAtFromTarget = _clAtFromTarget;
7941 _cfgLocal.ColorAtTo = _clAtTo;
7942 _cfgLocal.ColorListBackcolor = _clListBackcolor;
7943 _cfgLocal.ColorInputBackcolor = _clInputBackcolor;
7944 _cfgLocal.ColorInputFont = _clInputFont;
7945 _cfgLocal.FontInputFont = _fntInputFont;
7947 _cfgLocal.BrowserPath = SettingDialog.BrowserPath;
7948 _cfgLocal.UseRecommendStatus = SettingDialog.UseRecommendStatus;
7949 _cfgLocal.ProxyType = SettingDialog.SelectedProxyType;
7950 _cfgLocal.ProxyAddress = SettingDialog.ProxyAddress;
7951 _cfgLocal.ProxyPort = SettingDialog.ProxyPort;
7952 _cfgLocal.ProxyUser = SettingDialog.ProxyUser;
7953 _cfgLocal.ProxyPassword = SettingDialog.ProxyPassword;
7954 if (_ignoreConfigSave) return;
7959 private void SaveConfigsTabs()
7961 SettingTabs tabSetting = new SettingTabs();
7962 for (int i = 0; i < ListTab.TabPages.Count; i++)
7964 if (_statuses.Tabs[ListTab.TabPages[i].Text].TabType != MyCommon.TabUsageType.Related) tabSetting.Tabs.Add(_statuses.Tabs[ListTab.TabPages[i].Text]);
7969 private void SaveLogMenuItem_Click(object sender, EventArgs e)
7971 DialogResult rslt = MessageBox.Show(string.Format(Properties.Resources.SaveLogMenuItem_ClickText1, Environment.NewLine),
7972 Properties.Resources.SaveLogMenuItem_ClickText2,
7973 MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
7974 if (rslt == DialogResult.Cancel) return;
7976 SaveFileDialog1.FileName = MyCommon.GetAssemblyName() + "Posts" + DateTime.Now.ToString("yyMMdd-HHmmss") + ".tsv";
7977 SaveFileDialog1.InitialDirectory = Application.ExecutablePath;
7978 SaveFileDialog1.Filter = Properties.Resources.SaveLogMenuItem_ClickText3;
7979 SaveFileDialog1.FilterIndex = 0;
7980 SaveFileDialog1.Title = Properties.Resources.SaveLogMenuItem_ClickText4;
7981 SaveFileDialog1.RestoreDirectory = true;
7983 if (SaveFileDialog1.ShowDialog() == DialogResult.OK)
7985 if (!SaveFileDialog1.ValidateNames) return;
7986 using (StreamWriter sw = new StreamWriter(SaveFileDialog1.FileName, false, Encoding.UTF8))
7988 if (rslt == DialogResult.Yes)
7991 for (int idx = 0; idx < _curList.VirtualListSize; idx++)
7993 PostClass post = _statuses[_curTab.Text, idx];
7994 string protect = "";
7995 if (post.IsProtect) protect = "Protect";
7996 sw.WriteLine(post.Nickname + "\t" +
7997 "\"" + post.TextFromApi.Replace("\n", "").Replace("\"", "\"\"") + "\"" + "\t" +
7998 post.CreatedAt.ToString() + "\t" +
7999 post.ScreenName + "\t" +
8000 post.StatusId.ToString() + "\t" +
8001 post.ImageUrl + "\t" +
8002 "\"" + post.Text.Replace("\n", "").Replace("\"", "\"\"") + "\"" + "\t" +
8008 foreach (int idx in _curList.SelectedIndices)
8010 PostClass post = _statuses[_curTab.Text, idx];
8011 string protect = "";
8012 if (post.IsProtect) protect = "Protect";
8013 sw.WriteLine(post.Nickname + "\t" +
8014 "\"" + post.TextFromApi.Replace("\n", "").Replace("\"", "\"\"") + "\"" + "\t" +
8015 post.CreatedAt.ToString() + "\t" +
8016 post.ScreenName + "\t" +
8017 post.StatusId.ToString() + "\t" +
8018 post.ImageUrl + "\t" +
8019 "\"" + post.Text.Replace("\n", "").Replace("\"", "\"\"") + "\"" + "\t" +
8025 this.TopMost = SettingDialog.AlwaysTop;
8028 private void PostBrowser_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
8030 ModifierState State = GetModifierState(e.Control, e.Shift, e.Alt);
8031 if (State == ModifierState.NotFlags) return;
8032 bool KeyRes = CommonKeyDown(e.KeyCode, FocusedControl.PostBrowser, State);
8035 e.IsInputKey = true;
8038 public bool TabRename(ref string tabName)
8041 string newTabText = null;
8042 using (InputTabName inputName = new InputTabName())
8044 inputName.TabName = tabName;
8045 inputName.ShowDialog();
8046 if (inputName.DialogResult == DialogResult.Cancel) return false;
8047 newTabText = inputName.TabName;
8049 this.TopMost = SettingDialog.AlwaysTop;
8050 if (!string.IsNullOrEmpty(newTabText))
8053 for (int i = 0; i < ListTab.TabCount; i++)
8055 if (ListTab.TabPages[i].Text == newTabText)
8057 string tmp = string.Format(Properties.Resources.Tabs_DoubleClickText1, newTabText);
8058 MessageBox.Show(tmp, Properties.Resources.Tabs_DoubleClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
8062 //タブ名のリスト作り直し(デフォルトタブ以外は再作成)
8063 for (int i = 0; i < ListTab.TabCount; i++)
8065 if (ListTab.TabPages[i].Text == tabName)
8067 ListTab.TabPages[i].Text = newTabText;
8070 _statuses.RenameTab(tabName, newTabText);
8072 for (int i = 0; i < ListTab.TabCount; i++)
8074 if (_statuses.IsDistributableTab(ListTab.TabPages[i].Text))
8076 if (ListTab.TabPages[i].Text == tabName)
8078 ListTab.TabPages[i].Text = newTabText;
8082 SaveConfigsCommon();
8084 _rclickTabName = newTabText;
8085 tabName = newTabText;
8094 private void ListTab_MouseClick(object sender, MouseEventArgs e)
8096 if (e.Button == MouseButtons.Middle)
8098 for (int i = 0; i < this.ListTab.TabPages.Count; i++)
8100 if (this.ListTab.GetTabRect(i).Contains(e.Location))
8102 this.RemoveSpecifiedTab(this.ListTab.TabPages[i].Text, true);
8103 this.SaveConfigsTabs();
8110 private void Tabs_DoubleClick(object sender, MouseEventArgs e)
8112 string tn = ListTab.SelectedTab.Text;
8116 private void Tabs_MouseDown(object sender, MouseEventArgs e)
8118 if (SettingDialog.TabMouseLock) return;
8119 Point cpos = new Point(e.X, e.Y);
8120 if (e.Button == MouseButtons.Left)
8122 for (int i = 0; i < ListTab.TabPages.Count; i++)
8124 if (this.ListTab.GetTabRect(i).Contains(e.Location))
8127 _tabMouseDownPoint = e.Location;
8138 private void Tabs_DragEnter(object sender, DragEventArgs e)
8140 if (e.Data.GetDataPresent(typeof(TabPage)))
8141 e.Effect = DragDropEffects.Move;
8143 e.Effect = DragDropEffects.None;
8146 private void Tabs_DragDrop(object sender, DragEventArgs e)
8148 if (!e.Data.GetDataPresent(typeof(TabPage))) return;
8153 Point cpos = new Point(e.X, e.Y);
8154 Point spos = ListTab.PointToClient(cpos);
8156 for (i = 0; i < ListTab.TabPages.Count; i++)
8158 Rectangle rect = ListTab.GetTabRect(i);
8159 if (rect.Left <= spos.X && spos.X <= rect.Right &&
8160 rect.Top <= spos.Y && spos.Y <= rect.Bottom)
8162 tn = ListTab.TabPages[i].Text;
8163 if (spos.X <= (rect.Left + rect.Right) / 2)
8172 //タブのないところにドロップ->最後尾へ移動
8173 if (string.IsNullOrEmpty(tn))
8175 tn = ListTab.TabPages[ListTab.TabPages.Count - 1].Text;
8177 i = ListTab.TabPages.Count - 1;
8180 TabPage tp = (TabPage)e.Data.GetData(typeof(TabPage));
8181 if (tp.Text == tn) return;
8183 ReOrderTab(tp.Text, tn, bef);
8186 public void ReOrderTab(string targetTabText, string baseTabText, bool isBeforeBaseTab)
8189 for (baseIndex = 0; baseIndex < ListTab.TabPages.Count; baseIndex++)
8191 if (ListTab.TabPages[baseIndex].Text == baseTabText) break;
8194 ListTab.SuspendLayout();
8197 for (int j = 0; j < ListTab.TabPages.Count; j++)
8199 if (ListTab.TabPages[j].Text == targetTabText)
8201 mTp = ListTab.TabPages[j];
8202 ListTab.TabPages.Remove(mTp);
8203 if (j < baseIndex) baseIndex -= 1;
8207 if (isBeforeBaseTab)
8208 ListTab.TabPages.Insert(baseIndex, mTp);
8210 ListTab.TabPages.Insert(baseIndex + 1, mTp);
8212 ListTab.ResumeLayout();
8217 private void MakeReplyOrDirectStatus(bool isAuto = true, bool isReply = true, bool isAll = false)
8219 //isAuto:true=先頭に挿入、false=カーソル位置に挿入
8220 //isReply:true=@,false=DM
8221 if (!StatusText.Enabled) return;
8222 if (_curList == null) return;
8223 if (_curTab == null) return;
8224 if (!this.ExistCurrentPost) return;
8226 // 複数あてリプライはReplyではなく通常ポスト
8227 //↑仕様変更で全部リプライ扱いでOK(先頭ドット付加しない)
8228 //090403暫定でドットを付加しないようにだけ修正。単独と複数の処理は統合できると思われる。
8229 //090513 all @ replies 廃止の仕様変更によりドット付加に戻し(syo68k)
8231 if (_curList.SelectedIndices.Count > 0)
8234 if (_curList.SelectedIndices.Count == 1 && !isAll && this.ExistCurrentPost)
8237 if ((_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.DirectMessage && isAuto) || (!isAuto && !isReply))
8240 StatusText.Text = "D " + _curPost.ScreenName + " " + StatusText.Text;
8241 StatusText.SelectionStart = StatusText.Text.Length;
8244 _reply_to_name = "";
8247 if (string.IsNullOrEmpty(StatusText.Text))
8251 // ステータステキストが入力されていない場合先頭に@ユーザー名を追加する
8252 StatusText.Text = "@" + _curPost.ScreenName + " ";
8253 if (_curPost.RetweetedId > 0)
8255 _reply_to_id = _curPost.RetweetedId;
8259 _reply_to_id = _curPost.StatusId;
8261 _reply_to_name = _curPost.ScreenName;
8269 //1件選んでEnter or DoubleClick
8270 if (StatusText.Text.Contains("@" + _curPost.ScreenName + " "))
8272 if (_reply_to_id > 0 && _reply_to_name == _curPost.ScreenName)
8275 if (_curPost.RetweetedId > 0)
8277 _reply_to_id = _curPost.RetweetedId;
8281 _reply_to_id = _curPost.StatusId;
8283 _reply_to_name = _curPost.ScreenName;
8287 if (!StatusText.Text.StartsWith("@"))
8290 if (StatusText.Text.StartsWith(". "))
8293 StatusText.Text = StatusText.Text.Insert(2, "@" + _curPost.ScreenName + " ");
8295 _reply_to_name = "";
8300 StatusText.Text = "@" + _curPost.ScreenName + " " + StatusText.Text;
8301 if (_curPost.RetweetedId > 0)
8303 _reply_to_id = _curPost.RetweetedId;
8307 _reply_to_id = _curPost.StatusId;
8309 _reply_to_name = _curPost.ScreenName;
8316 StatusText.Text = ". @" + _curPost.ScreenName + " " + StatusText.Text;
8317 //StatusText.Text = "@" + _curPost.ScreenName + " " + StatusText.Text;
8319 _reply_to_name = "";
8324 //1件選んでCtrl-Rの場合(返信先操作せず)
8325 int sidx = StatusText.SelectionStart;
8326 string id = "@" + _curPost.ScreenName + " ";
8329 if (StatusText.Text.Substring(sidx - 1, 1) != " ")
8334 StatusText.Text = StatusText.Text.Insert(sidx, id);
8336 //if (StatusText.Text.StartsWith("@"))
8339 // StatusText.Text = ". " + StatusText.Text.Insert(sidx, " @" + _curPost.ScreenName + " ");
8340 // sidx += 5 + _curPost.ScreenName.Length;
8345 // StatusText.Text = StatusText.Text.Insert(sidx, " @" + _curPost.ScreenName + " ");
8346 // sidx += 3 + _curPost.ScreenName.Length;
8348 StatusText.SelectionStart = sidx;
8351 //_reply_to_name = null;
8359 if (!isAuto && !isReply) return;
8361 //C-S-rか、複数の宛先を選択中にEnter/DoubleClick/C-r/C-S-r
8365 //Enter or DoubleClick
8367 string sTxt = StatusText.Text;
8368 if (!sTxt.StartsWith(". "))
8372 _reply_to_name = "";
8374 for (int cnt = 0; cnt < _curList.SelectedIndices.Count; cnt++)
8376 PostClass post = _statuses[_curTab.Text, _curList.SelectedIndices[cnt]];
8377 if (!sTxt.Contains("@" + post.ScreenName + " "))
8379 sTxt = sTxt.Insert(2, "@" + post.ScreenName + " ");
8380 //sTxt = "@" + post.ScreenName + " " + sTxt;
8383 StatusText.Text = sTxt;
8388 if (_curList.SelectedIndices.Count > 1)
8393 int sidx = StatusText.SelectionStart;
8394 for (int cnt = 0; cnt < _curList.SelectedIndices.Count; cnt++)
8396 PostClass post = _statuses[_curTab.Text, _curList.SelectedIndices[cnt]];
8397 if (!ids.Contains("@" + post.ScreenName + " ") &&
8398 !post.ScreenName.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase))
8400 ids += "@" + post.ScreenName + " ";
8404 foreach (string nm in post.ReplyToList)
8406 if (!ids.Contains("@" + nm + " ") &&
8407 !nm.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase))
8409 Match m = Regex.Match(post.TextFromApi, "[@@](?<id>" + nm + ")([^a-zA-Z0-9]|$)", RegexOptions.IgnoreCase);
8411 ids += "@" + m.Result("${id}") + " ";
8413 ids += "@" + nm + " ";
8418 if (ids.Length == 0) return;
8419 if (!StatusText.Text.StartsWith(". "))
8421 StatusText.Text = ". " + StatusText.Text;
8424 _reply_to_name = "";
8428 if (StatusText.Text.Substring(sidx - 1, 1) != " ")
8433 StatusText.Text = StatusText.Text.Insert(sidx, ids);
8435 //if (StatusText.Text.StartsWith("@"))
8437 // StatusText.Text = ". " + StatusText.Text.Insert(sidx, ids);
8438 // sidx += 2 + ids.Length;
8442 // StatusText.Text = StatusText.Text.Insert(sidx, ids);
8443 // sidx += 1 + ids.Length;
8445 StatusText.SelectionStart = sidx;
8451 //1件のみ選択のC-S-r(返信元付加する可能性あり)
8454 int sidx = StatusText.SelectionStart;
8455 PostClass post = _curPost;
8456 if (!ids.Contains("@" + post.ScreenName + " ") &&
8457 !post.ScreenName.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase))
8459 ids += "@" + post.ScreenName + " ";
8461 foreach (string nm in post.ReplyToList)
8463 if (!ids.Contains("@" + nm + " ") &&
8464 !nm.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase))
8466 Match m = Regex.Match(post.TextFromApi, "[@@](?<id>" + nm + ")([^a-zA-Z0-9]|$)", RegexOptions.IgnoreCase);
8468 ids += "@" + m.Result("${id}") + " ";
8470 ids += "@" + nm + " ";
8473 if (!string.IsNullOrEmpty(post.RetweetedBy))
8475 if (!ids.Contains("@" + post.RetweetedBy + " ") &&
8476 !post.RetweetedBy.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase))
8478 ids += "@" + post.RetweetedBy + " ";
8481 if (ids.Length == 0) return;
8482 if (string.IsNullOrEmpty(StatusText.Text))
8485 StatusText.Text = ids;
8486 StatusText.SelectionStart = ids.Length;
8488 if (post.RetweetedId > 0)
8490 _reply_to_id = post.RetweetedId;
8494 _reply_to_id = post.StatusId;
8496 _reply_to_name = post.ScreenName;
8502 if (StatusText.Text.Substring(sidx - 1, 1) != " ")
8507 StatusText.Text = StatusText.Text.Insert(sidx, ids);
8509 StatusText.SelectionStart = sidx;
8515 StatusText.SelectionStart = StatusText.Text.Length;
8520 private void ListTab_MouseUp(object sender, MouseEventArgs e)
8525 private static int iconCnt = 0;
8526 private static int blinkCnt = 0;
8527 private static bool blink = false;
8528 private static bool idle = false;
8530 private void RefreshTasktrayIcon(bool forceRefresh)
8532 if (_colorize) Colorize();
8533 if (!TimerRefreshIcon.Enabled) return;
8534 //Static usCheckCnt As int = 0
8536 //Static iconDlListTopItem As ListViewItem = null
8538 if (forceRefresh) idle = false;
8540 //if (((ListView)ListTab.SelectedTab.Tag).TopItem == iconDlListTopItem)
8541 // ((ImageDictionary)this.TIconDic).PauseGetImage = false;
8543 // ((ImageDictionary)this.TIconDic).PauseGetImage = true;
8545 //iconDlListTopItem = ((ListView)ListTab.SelectedTab.Tag).TopItem;
8551 //if (usCheckCnt > 300) //1min
8554 // if (!this.IsReceivedUserStream)
8556 // TraceOut("ReconnectUserStream");
8557 // tw.ReconnectUserStream();
8562 foreach (BackgroundWorker bw in this._bw)
8564 if (bw != null && bw.IsBusy)
8579 SaveConfigsAll(true);
8584 NotifyIcon1.Icon = NIconRefresh[iconCnt];
8586 _myStatusError = false;
8590 TabClass tb = _statuses.GetTabByType(MyCommon.TabUsageType.Mentions);
8591 if (SettingDialog.ReplyIconState != MyCommon.REPLY_ICONSTATE.None && tb != null && tb.UnreadCount > 0)
8593 if (blinkCnt > 0) return;
8595 if (blink || SettingDialog.ReplyIconState == MyCommon.REPLY_ICONSTATE.StaticIcon)
8597 NotifyIcon1.Icon = ReplyIcon;
8601 NotifyIcon1.Icon = ReplyIconBlink;
8609 //優先度:エラー→オフライン→アイドル
8613 NotifyIcon1.Icon = NIconAtRed;
8616 if (_myStatusOnline)
8618 NotifyIcon1.Icon = NIconAt;
8622 NotifyIcon1.Icon = NIconAtSmoke;
8626 private void TimerRefreshIcon_Tick(object sender, EventArgs e)
8629 this.RefreshTasktrayIcon(false);
8632 private void ContextMenuTabProperty_Opening(object sender, CancelEventArgs e)
8634 //右クリックの場合はタブ名が設定済。アプリケーションキーの場合は現在のタブを対象とする
8635 if (string.IsNullOrEmpty(_rclickTabName) || sender != ContextMenuTabProperty)
8637 if (ListTab != null && ListTab.SelectedTab != null)
8638 _rclickTabName = ListTab.SelectedTab.Text;
8643 if (_statuses == null) return;
8644 if (_statuses.Tabs == null) return;
8646 TabClass tb = _statuses.Tabs[_rclickTabName];
8647 if (tb == null) return;
8649 NotifyDispMenuItem.Checked = tb.Notify;
8650 this.NotifyTbMenuItem.Checked = tb.Notify;
8652 soundfileListup = true;
8653 SoundFileComboBox.Items.Clear();
8654 this.SoundFileTbComboBox.Items.Clear();
8655 SoundFileComboBox.Items.Add("");
8656 this.SoundFileTbComboBox.Items.Add("");
8657 DirectoryInfo oDir = new DirectoryInfo(Application.StartupPath + Path.DirectorySeparatorChar);
8658 if (Directory.Exists(Path.Combine(Application.StartupPath, "Sounds")))
8660 oDir = oDir.GetDirectories("Sounds")[0];
8662 foreach (FileInfo oFile in oDir.GetFiles("*.wav"))
8664 SoundFileComboBox.Items.Add(oFile.Name);
8665 this.SoundFileTbComboBox.Items.Add(oFile.Name);
8667 int idx = SoundFileComboBox.Items.IndexOf(tb.SoundFile);
8668 if (idx == -1) idx = 0;
8669 SoundFileComboBox.SelectedIndex = idx;
8670 this.SoundFileTbComboBox.SelectedIndex = idx;
8671 soundfileListup = false;
8672 UreadManageMenuItem.Checked = tb.UnreadManage;
8673 this.UnreadMngTbMenuItem.Checked = tb.UnreadManage;
8675 TabMenuControl(_rclickTabName);
8678 private void TabMenuControl(string tabName)
8680 this.FilterEditMenuItem.Enabled = true;
8681 this.EditRuleTbMenuItem.Enabled = true;
8683 if (_statuses.IsDefaultTab(tabName))
8685 this.ProtectTabMenuItem.Enabled = false;
8686 this.ProtectTbMenuItem.Enabled = false;
8690 this.ProtectTabMenuItem.Enabled = true;
8691 this.ProtectTbMenuItem.Enabled = true;
8694 if (_statuses.IsDefaultTab(tabName) || _statuses.Tabs[tabName].Protected)
8696 this.ProtectTabMenuItem.Checked = true;
8697 this.ProtectTbMenuItem.Checked = true;
8698 this.DeleteTabMenuItem.Enabled = false;
8699 this.DeleteTbMenuItem.Enabled = false;
8703 this.ProtectTabMenuItem.Checked = false;
8704 this.ProtectTbMenuItem.Checked = false;
8705 this.DeleteTabMenuItem.Enabled = true;
8706 this.DeleteTbMenuItem.Enabled = true;
8710 private void ProtectTabMenuItem_Click(object sender, EventArgs e)
8712 var checkState = ((ToolStripMenuItem)sender).Checked;
8715 this.ProtectTbMenuItem.Checked = checkState;
8716 this.ProtectTabMenuItem.Checked = checkState;
8719 this.DeleteTabMenuItem.Enabled = !checkState;
8720 this.DeleteTbMenuItem.Enabled = !checkState;
8722 if (string.IsNullOrEmpty(_rclickTabName)) return;
8723 _statuses.Tabs[_rclickTabName].Protected = checkState;
8728 private void UreadManageMenuItem_Click(object sender, EventArgs e)
8730 UreadManageMenuItem.Checked = ((ToolStripMenuItem)sender).Checked;
8731 this.UnreadMngTbMenuItem.Checked = UreadManageMenuItem.Checked;
8733 if (string.IsNullOrEmpty(_rclickTabName)) return;
8734 ChangeTabUnreadManage(_rclickTabName, UreadManageMenuItem.Checked);
8739 public void ChangeTabUnreadManage(string tabName, bool isManage)
8742 for (idx = 0; idx < ListTab.TabCount; idx++)
8744 if (ListTab.TabPages[idx].Text == tabName) break;
8747 _statuses.SetTabUnreadManage(tabName, isManage);
8748 if (SettingDialog.TabIconDisp)
8750 if (_statuses.Tabs[tabName].UnreadCount > 0)
8751 ListTab.TabPages[idx].ImageIndex = 0;
8753 ListTab.TabPages[idx].ImageIndex = -1;
8756 if (_curTab.Text == tabName)
8758 this.PurgeListViewItemCache();
8762 SetMainWindowTitle();
8763 SetStatusLabelUrl();
8764 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
8767 private void NotifyDispMenuItem_Click(object sender, EventArgs e)
8769 NotifyDispMenuItem.Checked = ((ToolStripMenuItem)sender).Checked;
8770 this.NotifyTbMenuItem.Checked = NotifyDispMenuItem.Checked;
8772 if (string.IsNullOrEmpty(_rclickTabName)) return;
8774 _statuses.Tabs[_rclickTabName].Notify = NotifyDispMenuItem.Checked;
8779 private void SoundFileComboBox_SelectedIndexChanged(object sender, EventArgs e)
8781 if (soundfileListup || string.IsNullOrEmpty(_rclickTabName)) return;
8783 _statuses.Tabs[_rclickTabName].SoundFile = (string)((ToolStripComboBox)sender).SelectedItem;
8788 private void DeleteTabMenuItem_Click(object sender, EventArgs e)
8790 if (string.IsNullOrEmpty(_rclickTabName) || sender == this.DeleteTbMenuItem) _rclickTabName = ListTab.SelectedTab.Text;
8792 RemoveSpecifiedTab(_rclickTabName, true);
8796 private void FilterEditMenuItem_Click(object sender, EventArgs e)
8798 if (string.IsNullOrEmpty(_rclickTabName)) _rclickTabName = _statuses.GetTabByType(MyCommon.TabUsageType.Home).TabName;
8799 fltDialog.SetCurrent(_rclickTabName);
8800 fltDialog.ShowDialog(this);
8801 this.TopMost = SettingDialog.AlwaysTop;
8805 this.Cursor = Cursors.WaitCursor;
8806 this.PurgeListViewItemCache();
8809 _statuses.FilterAll();
8810 foreach (TabPage tb in ListTab.TabPages)
8812 ((DetailsListView)tb.Tag).VirtualListSize = _statuses.Tabs[tb.Text].AllCount;
8813 if (_statuses.Tabs[tb.Text].UnreadCount > 0)
8815 if (SettingDialog.TabIconDisp)
8820 if (SettingDialog.TabIconDisp)
8824 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
8828 this.Cursor = Cursors.Default;
8833 private void AddTabMenuItem_Click(object sender, EventArgs e)
8835 string tabName = null;
8836 MyCommon.TabUsageType tabUsage;
8837 using (InputTabName inputName = new InputTabName())
8839 inputName.TabName = _statuses.GetUniqueTabName();
8840 inputName.IsShowUsage = true;
8841 inputName.ShowDialog();
8842 if (inputName.DialogResult == DialogResult.Cancel) return;
8843 tabName = inputName.TabName;
8844 tabUsage = inputName.Usage;
8846 this.TopMost = SettingDialog.AlwaysTop;
8847 if (!string.IsNullOrEmpty(tabName))
8850 ListElement list = null;
8851 if (tabUsage == MyCommon.TabUsageType.Lists)
8853 using (ListAvailable listAvail = new ListAvailable())
8855 if (listAvail.ShowDialog(this) == DialogResult.Cancel) return;
8856 if (listAvail.SelectedList == null) return;
8857 list = listAvail.SelectedList;
8860 if (!_statuses.AddTab(tabName, tabUsage, list) || !AddNewTab(tabName, false, tabUsage, list))
8862 string tmp = string.Format(Properties.Resources.AddTabMenuItem_ClickText1, tabName);
8863 MessageBox.Show(tmp, Properties.Resources.AddTabMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
8869 if (tabUsage == MyCommon.TabUsageType.PublicSearch)
8871 ListTab.SelectedIndex = ListTab.TabPages.Count - 1;
8872 ListTabSelect(ListTab.TabPages[ListTab.TabPages.Count - 1]);
8873 ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"].Focus();
8875 if (tabUsage == MyCommon.TabUsageType.Lists)
8877 ListTab.SelectedIndex = ListTab.TabPages.Count - 1;
8878 ListTabSelect(ListTab.TabPages[ListTab.TabPages.Count - 1]);
8879 GetTimeline(MyCommon.WORKERTYPE.List, 1, 0, tabName);
8885 private void TabMenuItem_Click(object sender, EventArgs e)
8888 foreach (int idx in _curList.SelectedIndices)
8892 if (!SelectTab(out tabName)) return;
8894 fltDialog.SetCurrent(tabName);
8895 if (_statuses[_curTab.Text, idx].RetweetedId == 0)
8897 fltDialog.AddNewFilter(_statuses[_curTab.Text, idx].ScreenName, _statuses[_curTab.Text, idx].TextFromApi);
8901 fltDialog.AddNewFilter(_statuses[_curTab.Text, idx].RetweetedBy, _statuses[_curTab.Text, idx].TextFromApi);
8903 fltDialog.ShowDialog(this);
8904 this.TopMost = SettingDialog.AlwaysTop;
8909 this.Cursor = Cursors.WaitCursor;
8910 this.PurgeListViewItemCache();
8913 _statuses.FilterAll();
8914 foreach (TabPage tb in ListTab.TabPages)
8916 ((DetailsListView)tb.Tag).VirtualListSize = _statuses.Tabs[tb.Text].AllCount;
8917 if (_statuses.Tabs[tb.Text].UnreadCount > 0)
8919 if (SettingDialog.TabIconDisp)
8924 if (SettingDialog.TabIconDisp)
8928 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
8932 this.Cursor = Cursors.Default;
8935 if (this.ListTab.SelectedTab != null &&
8936 ((DetailsListView)this.ListTab.SelectedTab.Tag).SelectedIndices.Count > 0)
8938 _curPost = _statuses[this.ListTab.SelectedTab.Text, ((DetailsListView)this.ListTab.SelectedTab.Tag).SelectedIndices[0]];
8942 protected override bool ProcessDialogKey(Keys keyData)
8944 //TextBox1でEnterを押してもビープ音が鳴らないようにする
8945 if ((keyData & Keys.KeyCode) == Keys.Enter)
8947 if (StatusText.Focused)
8949 bool _NewLine = false;
8952 if (SettingDialog.PostCtrlEnter) //Ctrl+Enter投稿時
8954 if (StatusText.Multiline)
8956 if ((keyData & Keys.Shift) == Keys.Shift && (keyData & Keys.Control) != Keys.Control) _NewLine = true;
8958 if ((keyData & Keys.Control) == Keys.Control) _Post = true;
8962 if (((keyData & Keys.Control) == Keys.Control)) _Post = true;
8966 else if (SettingDialog.PostShiftEnter) //SHift+Enter投稿時
8968 if (StatusText.Multiline)
8970 if ((keyData & Keys.Control) == Keys.Control && (keyData & Keys.Shift) != Keys.Shift) _NewLine = true;
8972 if ((keyData & Keys.Shift) == Keys.Shift) _Post = true;
8976 if (((keyData & Keys.Shift) == Keys.Shift)) _Post = true;
8982 if (StatusText.Multiline)
8984 if ((keyData & Keys.Shift) == Keys.Shift && (keyData & Keys.Control) != Keys.Control) _NewLine = true;
8986 if (((keyData & Keys.Control) != Keys.Control && (keyData & Keys.Shift) != Keys.Shift) ||
8987 ((keyData & Keys.Control) == Keys.Control && (keyData & Keys.Shift) == Keys.Shift)) _Post = true;
8991 if (((keyData & Keys.Shift) == Keys.Shift) ||
8992 (((keyData & Keys.Control) != Keys.Control) &&
8993 ((keyData & Keys.Shift) != Keys.Shift))) _Post = true;
8999 int pos1 = StatusText.SelectionStart;
9000 if (StatusText.SelectionLength > 0)
9002 StatusText.Text = StatusText.Text.Remove(pos1, StatusText.SelectionLength); //選択状態文字列削除
9004 StatusText.Text = StatusText.Text.Insert(pos1, Environment.NewLine); //改行挿入
9005 StatusText.SelectionStart = pos1 + Environment.NewLine.Length; //カーソルを改行の次の文字へ移動
9010 PostButton_Click(null, null);
9014 else if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.PublicSearch &&
9015 (ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"].Focused ||
9016 ListTab.SelectedTab.Controls["panelSearch"].Controls["comboLang"].Focused))
9018 this.SearchButton_Click(ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"], null);
9023 return base.ProcessDialogKey(keyData);
9026 private void ReplyAllStripMenuItem_Click(object sender, EventArgs e)
9028 MakeReplyOrDirectStatus(false, true, true);
9031 private void IDRuleMenuItem_Click(object sender, EventArgs e)
9036 if (_curList.SelectedIndices.Count == 0) return;
9039 if (!SelectTab(out tabName)) return;
9043 MoveOrCopy(ref mv, ref mk);
9045 List<string> ids = new List<string>();
9046 foreach (int idx in _curList.SelectedIndices)
9048 PostClass post = _statuses[_curTab.Text, idx];
9049 if (!ids.Contains(post.ScreenName))
9051 FiltersClass fc = new FiltersClass();
9052 ids.Add(post.ScreenName);
9053 if (post.RetweetedId == 0)
9055 fc.NameFilter = post.ScreenName;
9059 fc.NameFilter = post.RetweetedBy;
9061 fc.SearchBoth = true;
9064 fc.UseRegex = false;
9065 fc.SearchUrl = false;
9066 _statuses.Tabs[tabName].AddFilter(fc);
9071 List<string> atids = new List<string>();
9072 foreach (string id in ids)
9074 atids.Add("@" + id);
9076 int cnt = AtIdSupl.ItemCount;
9077 AtIdSupl.AddRangeItem(atids.ToArray());
9078 if (AtIdSupl.ItemCount != cnt) _modifySettingAtId = true;
9083 this.Cursor = Cursors.WaitCursor;
9084 this.PurgeListViewItemCache();
9087 _statuses.FilterAll();
9088 foreach (TabPage tb in ListTab.TabPages)
9090 ((DetailsListView)tb.Tag).VirtualListSize = _statuses.Tabs[tb.Text].AllCount;
9091 if (_statuses.ContainsTab(tb.Text))
9093 if (_statuses.Tabs[tb.Text].UnreadCount > 0)
9095 if (SettingDialog.TabIconDisp)
9100 if (SettingDialog.TabIconDisp)
9105 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
9109 this.Cursor = Cursors.Default;
9114 private bool SelectTab(out string tabName)
9121 using (var dialog = new TabsDialog(_statuses))
9123 if (dialog.ShowDialog(this) == DialogResult.Cancel) return false;
9125 var selectedTab = dialog.SelectedTab;
9126 tabName = selectedTab == null ? null : selectedTab.TabName;
9129 ListTab.SelectedTab.Focus();
9131 if (tabName == null)
9133 using (InputTabName inputName = new InputTabName())
9135 inputName.TabName = _statuses.GetUniqueTabName();
9136 inputName.ShowDialog();
9137 if (inputName.DialogResult == DialogResult.Cancel) return false;
9138 tabName = inputName.TabName;
9140 this.TopMost = SettingDialog.AlwaysTop;
9141 if (!string.IsNullOrEmpty(tabName))
9143 if (!_statuses.AddTab(tabName, MyCommon.TabUsageType.UserDefined, null) || !AddNewTab(tabName, false, MyCommon.TabUsageType.UserDefined))
9145 string tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText2, tabName);
9146 MessageBox.Show(tmp, Properties.Resources.IDRuleMenuItem_ClickText3, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
9164 private void MoveOrCopy(ref bool move, ref bool mark)
9168 string _tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText4, Environment.NewLine);
9169 if (MessageBox.Show(_tmp, Properties.Resources.IDRuleMenuItem_ClickText5, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
9177 string _tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText6, Environment.NewLine);
9178 if (MessageBox.Show(_tmp, Properties.Resources.IDRuleMenuItem_ClickText7, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
9184 private void CopySTOTMenuItem_Click(object sender, EventArgs e)
9189 private void CopyURLMenuItem_Click(object sender, EventArgs e)
9194 private void SelectAllMenuItem_Click(object sender, EventArgs e)
9196 if (StatusText.Focused)
9199 StatusText.SelectAll();
9203 // ListView上でのCtrl+A
9204 for (int i = 0; i < _curList.VirtualListSize; i++)
9206 _curList.SelectedIndices.Add(i);
9211 private void MoveMiddle()
9217 if (_curList.SelectedIndices.Count == 0) return;
9219 int idx = _curList.SelectedIndices[0];
9221 _item = _curList.GetItemAt(0, 25);
9227 _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1);
9229 idx2 = _curList.VirtualListSize - 1;
9233 idx -= Math.Abs(idx1 - idx2) / 2;
9234 if (idx < 0) idx = 0;
9236 _curList.EnsureVisible(_curList.VirtualListSize - 1);
9237 _curList.EnsureVisible(idx);
9240 private void OpenURLMenuItem_Click(object sender, EventArgs e)
9242 if (PostBrowser.Document.Links.Count > 0)
9244 UrlDialog.ClearUrl();
9246 string openUrlStr = "";
9248 if (PostBrowser.Document.Links.Count == 1)
9253 urlStr = MyCommon.IDNDecode(PostBrowser.Document.Links[0].GetAttribute("href"));
9255 catch (ArgumentException)
9264 if (string.IsNullOrEmpty(urlStr)) return;
9265 openUrlStr = MyCommon.urlEncodeMultibyteChar(urlStr);
9269 foreach (HtmlElement linkElm in PostBrowser.Document.Links)
9272 string linkText = "";
9276 urlStr = linkElm.GetAttribute("title");
9277 href = MyCommon.IDNDecode(linkElm.GetAttribute("href"));
9278 if (string.IsNullOrEmpty(urlStr)) urlStr = href;
9279 linkText = linkElm.InnerText;
9280 if (!linkText.StartsWith("http") && !linkText.StartsWith("#") && !linkText.Contains("."))
9282 linkText = "@" + linkText;
9285 catch (ArgumentException)
9294 if (string.IsNullOrEmpty(urlStr)) continue;
9295 UrlDialog.AddUrl(new OpenUrlItem(linkText, MyCommon.urlEncodeMultibyteChar(urlStr), href));
9299 if (UrlDialog.ShowDialog() == DialogResult.OK)
9301 openUrlStr = UrlDialog.SelectedUrl;
9308 this.TopMost = SettingDialog.AlwaysTop;
9310 if (string.IsNullOrEmpty(openUrlStr)) return;
9312 if (openUrlStr.StartsWith("http://twitter.com/search?q=") ||
9313 openUrlStr.StartsWith("https://twitter.com/search?q="))
9316 string urlStr = Uri.UnescapeDataString(openUrlStr);
9317 string hash = urlStr.Substring(urlStr.IndexOf("#"));
9318 HashSupl.AddItem(hash);
9319 HashMgr.AddHashToHistory(hash.Trim(), false);
9320 AddNewTabForSearch(hash);
9325 Match m = Regex.Match(openUrlStr, "^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)$");
9326 if (SettingDialog.OpenUserTimeline && m.Success && IsTwitterId(m.Result("${ScreenName}")))
9327 this.AddNewTabForUserTimeline(m.Result("${ScreenName}"));
9329 OpenUriAsync(openUrlStr);
9335 private void ClearTabMenuItem_Click(object sender, EventArgs e)
9337 if (string.IsNullOrEmpty(_rclickTabName)) return;
9338 ClearTab(_rclickTabName, true);
9341 private void ClearTab(string tabName, bool showWarning)
9345 string tmp = string.Format(Properties.Resources.ClearTabMenuItem_ClickText1, Environment.NewLine);
9346 if (MessageBox.Show(tmp, tabName + " " + Properties.Resources.ClearTabMenuItem_ClickText2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
9352 _statuses.ClearTabIds(tabName);
9353 if (ListTab.SelectedTab.Text == tabName)
9356 _anchorFlag = false;
9357 this.PurgeListViewItemCache();
9358 _itemCacheIndex = -1;
9362 foreach (TabPage tb in ListTab.TabPages)
9364 if (tb.Text == tabName)
9367 ((DetailsListView)tb.Tag).VirtualListSize = 0;
9371 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
9373 SetMainWindowTitle();
9374 SetStatusLabelUrl();
9377 private static long followers = 0;
9379 private void SetMainWindowTitle()
9382 StringBuilder ttl = new StringBuilder(256);
9385 if (SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.None &&
9386 SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.Post &&
9387 SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.Ver &&
9388 SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.OwnStatus)
9390 foreach (string key in _statuses.Tabs.Keys)
9392 ur += _statuses.Tabs[key].UnreadCount;
9393 al += _statuses.Tabs[key].AllCount;
9397 if (SettingDialog.DispUsername) ttl.Append(tw.Username).Append(" - ");
9398 ttl.Append(Application.ProductName);
9400 switch (SettingDialog.DispLatestPost)
9402 case MyCommon.DispTitleEnum.Ver:
9403 ttl.Append("Ver:").Append(MyCommon.GetReadableVersion());
9405 case MyCommon.DispTitleEnum.Post:
9406 if (_history != null && _history.Count > 1)
9407 ttl.Append(_history[_history.Count - 2].status.Replace("\r\n", " "));
9409 case MyCommon.DispTitleEnum.UnreadRepCount:
9410 ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText1, _statuses.GetTabByType(MyCommon.TabUsageType.Mentions).UnreadCount + _statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage).UnreadCount);
9412 case MyCommon.DispTitleEnum.UnreadAllCount:
9413 ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText2, ur);
9415 case MyCommon.DispTitleEnum.UnreadAllRepCount:
9416 ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText3, ur, _statuses.GetTabByType(MyCommon.TabUsageType.Mentions).UnreadCount + _statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage).UnreadCount);
9418 case MyCommon.DispTitleEnum.UnreadCountAllCount:
9419 ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText4, ur, al);
9421 case MyCommon.DispTitleEnum.OwnStatus:
9422 if (followers == 0 && tw.FollowersCount > 0) followers = tw.FollowersCount;
9423 ttl.AppendFormat(Properties.Resources.OwnStatusTitle, tw.StatusesCount, tw.FriendsCount, tw.FollowersCount, tw.FollowersCount - followers);
9429 this.Text = ttl.ToString();
9431 catch (AccessViolationException)
9433 //原因不明。ポスト内容に依存か?たまーに発生するが再現せず。
9437 private string GetStatusLabelText()
9440 //タブ未読数/タブ発言数 全未読数/総発言数 (未読@+未読DM数)
9441 if (_statuses == null) return "";
9442 TabClass tbRep = _statuses.GetTabByType(MyCommon.TabUsageType.Mentions);
9443 TabClass tbDm = _statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage);
9444 if (tbRep == null || tbDm == null) return "";
9445 int urat = tbRep.UnreadCount + tbDm.UnreadCount;
9450 StringBuilder slbl = new StringBuilder(256);
9453 foreach (string key in _statuses.Tabs.Keys)
9455 ur += _statuses.Tabs[key].UnreadCount;
9456 al += _statuses.Tabs[key].AllCount;
9457 if (key.Equals(_curTab.Text))
9459 tur = _statuses.Tabs[key].UnreadCount;
9460 tal = _statuses.Tabs[key].AllCount;
9470 UnreadAtCounter = urat;
9472 slbl.AppendFormat(Properties.Resources.SetStatusLabelText1, tur, tal, ur, al, urat, _postTimestamps.Count, _favTimestamps.Count, _tlCount);
9473 if (SettingDialog.TimelinePeriodInt == 0)
9475 slbl.Append(Properties.Resources.SetStatusLabelText2);
9479 slbl.Append(SettingDialog.TimelinePeriodInt.ToString() + Properties.Resources.SetStatusLabelText3);
9481 return slbl.ToString();
9484 private void TwitterApiStatus_AccessLimitUpdated(object sender, EventArgs e)
9488 if (this.InvokeRequired && !this.IsDisposed)
9490 this.Invoke((MethodInvoker)(() => this.TwitterApiStatus_AccessLimitUpdated(sender, e)));
9494 if (sender is TwitterApiStatus11 && this._apiGauge.API11Enabled)
9496 var endpointName = (e as TwitterApiStatus11.AccessLimitUpdatedEventArgs).EndpointName;
9497 if (endpointName == "/statuses/home_timeline" || endpointName == null)
9499 this._apiGauge.ApiLimit = MyCommon.TwitterApiInfo11.AccessLimit["/statuses/home_timeline"];
9502 else if (sender is TwitterApiStatus && !this._apiGauge.API11Enabled)
9504 this._apiGauge.ApiLimit = MyCommon.TwitterApiInfo.AccessLimit;
9508 catch (ObjectDisposedException)
9512 catch (InvalidOperationException)
9518 private void SetStatusLabelUrl()
9520 StatusLabelUrl.Text = GetStatusLabelText();
9523 public void SetStatusLabel(string text)
9525 StatusLabel.Text = text;
9528 private static StringBuilder ur = new StringBuilder(64);
9530 private void SetNotifyIconText()
9532 // タスクトレイアイコンのツールチップテキスト書き換え
9534 ur.Remove(0, ur.Length);
9535 if (SettingDialog.DispUsername)
9537 ur.Append(tw.Username);
9540 ur.Append(Application.ProductName);
9542 ur.Append("(Debug Build)");
9544 if (UnreadCounter != -1 && UnreadAtCounter != -1)
9547 ur.Append(UnreadCounter);
9549 ur.Append(UnreadAtCounter);
9552 NotifyIcon1.Text = ur.ToString();
9555 internal void CheckReplyTo(string StatusText)
9559 m = Regex.Matches(StatusText, Twitter.HASHTAG, RegexOptions.IgnoreCase);
9561 foreach (Match hm in m)
9563 if (!hstr.Contains("#" + hm.Result("$3") + " "))
9565 hstr += "#" + hm.Result("$3") + " ";
9566 HashSupl.AddItem("#" + hm.Result("$3"));
9569 if (!string.IsNullOrEmpty(HashMgr.UseHash) && !hstr.Contains(HashMgr.UseHash + " "))
9571 hstr += HashMgr.UseHash;
9573 if (!string.IsNullOrEmpty(hstr)) HashMgr.AddHashToHistory(hstr.Trim(), false);
9575 // 本当にリプライ先指定すべきかどうかの判定
9576 m = Regex.Matches(StatusText, "(^|[ -/:-@[-^`{-~])(?<id>@[a-zA-Z0-9_]+)");
9578 if (SettingDialog.UseAtIdSupplement)
9580 int bCnt = AtIdSupl.ItemCount;
9581 foreach (Match mid in m)
9583 AtIdSupl.AddItem(mid.Result("${id}"));
9585 if (bCnt != AtIdSupl.ItemCount) _modifySettingAtId = true;
9588 // リプライ先ステータスIDの指定がない場合は指定しない
9589 if (_reply_to_id == 0) return;
9591 // リプライ先ユーザー名がない場合も指定しない
9592 if (string.IsNullOrEmpty(_reply_to_name))
9599 // 次の条件を満たす場合に in_reply_to_status_id 指定
9600 // 1. Twitterによりリンクと判定される @idが文中に1つ含まれる (2009/5/28 リンク化される@IDのみカウントするように修正)
9601 // 2. リプライ先ステータスIDが設定されている(リストをダブルクリックで返信している)
9602 // 3. 文中に含まれた@idがリプライ先のポスト者のIDと一致する
9606 if (StatusText.StartsWith("@"))
9608 if (StatusText.StartsWith("@" + _reply_to_name)) return;
9612 foreach (Match mid in m)
9614 if (StatusText.Contains("QT " + mid.Result("${id}") + ":") && mid.Result("${id}") == "@" + _reply_to_name) return;
9620 _reply_to_name = "";
9624 private void TweenMain_Resize(object sender, EventArgs e)
9626 if (!_initialLayout && SettingDialog.MinimizeToTray && WindowState == FormWindowState.Minimized)
9628 this.Visible = false;
9630 if (_initialLayout && _cfgLocal != null && this.WindowState == FormWindowState.Normal && this.Visible)
9632 this.ClientSize = _cfgLocal.FormSize;
9633 //_mySize = this.ClientSize; //サイズ保持(最小化・最大化されたまま終了した場合の対応用)
9634 this.DesktopLocation = _cfgLocal.FormLocation;
9635 //_myLoc = this.DesktopLocation; //位置保持(最小化・最大化されたまま終了した場合の対応用)
9636 //if (_cfgLocal.AdSplitterDistance > this.SplitContainer4.Panel1MinSize &&
9637 // _cfgLocal.AdSplitterDistance < this.SplitContainer4.Height - this.SplitContainer4.Panel2MinSize - this.SplitContainer4.SplitterWidth)
9639 // this.SplitContainer4.SplitterDistance = _cfgLocal.AdSplitterDistance; //Splitterの位置設定
9641 if (_cfgLocal.SplitterDistance > this.SplitContainer1.Panel1MinSize &&
9642 _cfgLocal.SplitterDistance < this.SplitContainer1.Height - this.SplitContainer1.Panel2MinSize - this.SplitContainer1.SplitterWidth)
9644 this.SplitContainer1.SplitterDistance = _cfgLocal.SplitterDistance; //Splitterの位置設定
9647 StatusText.Multiline = _cfgLocal.StatusMultiline;
9648 if (StatusText.Multiline)
9650 int dis = SplitContainer2.Height - _cfgLocal.StatusTextHeight - SplitContainer2.SplitterWidth;
9651 if (dis > SplitContainer2.Panel1MinSize && dis < SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth)
9653 SplitContainer2.SplitterDistance = SplitContainer2.Height - _cfgLocal.StatusTextHeight - SplitContainer2.SplitterWidth;
9655 StatusText.Height = _cfgLocal.StatusTextHeight;
9659 if (SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth > 0)
9661 SplitContainer2.SplitterDistance = SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth;
9664 if (_cfgLocal.PreviewDistance > this.SplitContainer3.Panel1MinSize && _cfgLocal.PreviewDistance < this.SplitContainer3.Width - this.SplitContainer3.Panel2MinSize - this.SplitContainer3.SplitterWidth)
9666 this.SplitContainer3.SplitterDistance = _cfgLocal.PreviewDistance;
9668 _initialLayout = false;
9670 if (this.WindowState != FormWindowState.Minimized)
9672 _formWindowState = this.WindowState;
9676 private void PlaySoundMenuItem_CheckedChanged(object sender, EventArgs e)
9678 PlaySoundMenuItem.Checked = ((ToolStripMenuItem)sender).Checked;
9679 this.PlaySoundFileMenuItem.Checked = PlaySoundMenuItem.Checked;
9680 if (PlaySoundMenuItem.Checked)
9682 SettingDialog.PlaySound = true;
9686 SettingDialog.PlaySound = false;
9688 _modifySettingCommon = true;
9691 private void SplitContainer1_SplitterMoved(object sender, SplitterEventArgs e)
9693 if (this.WindowState == FormWindowState.Normal && !_initialLayout)
9695 _mySpDis = SplitContainer1.SplitterDistance;
9696 if (StatusText.Multiline) _mySpDis2 = StatusText.Height;
9697 _modifySettingLocal = true;
9701 private void doRepliedStatusOpen()
9703 if (this.ExistCurrentPost && _curPost.InReplyToUser != null && _curPost.InReplyToStatusId > 0)
9705 if (MyCommon.IsKeyDown(Keys.Shift))
9707 OpenUriAsync(MyCommon.GetStatusUrl(_curPost.InReplyToUser, _curPost.InReplyToStatusId));
9710 if (_statuses.ContainsKey(_curPost.InReplyToStatusId))
9712 PostClass repPost = _statuses[_curPost.InReplyToStatusId];
9713 MessageBox.Show(repPost.ScreenName + " / " + repPost.Nickname + " (" + repPost.CreatedAt.ToString() + ")" + Environment.NewLine + repPost.TextFromApi);
9717 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.Lists | MyCommon.TabUsageType.PublicSearch))
9719 if (tb == null || !tb.Contains(_curPost.InReplyToStatusId)) break;
9720 PostClass repPost = _statuses[_curPost.InReplyToStatusId];
9721 MessageBox.Show(repPost.ScreenName + " / " + repPost.Nickname + " (" + repPost.CreatedAt.ToString() + ")" + Environment.NewLine + repPost.TextFromApi);
9724 OpenUriAsync(MyCommon.GetStatusUrl(_curPost.InReplyToUser, _curPost.InReplyToStatusId));
9729 private void RepliedStatusOpenMenuItem_Click(object sender, EventArgs e)
9731 doRepliedStatusOpen();
9734 private void ContextMenuUserPicture_Opening(object sender, CancelEventArgs e)
9736 //発言詳細のアイコン右クリック時のメニュー制御
9737 if (_curList.SelectedIndices.Count > 0 && _curPost != null)
9739 string name = _curPost.ImageUrl;
9740 if (name != null && name.Length > 0)
9742 int idx = name.LastIndexOf('/');
9745 name = Path.GetFileName(name.Substring(idx));
9746 if (name.Contains("_normal.") || name.EndsWith("_normal"))
9748 name = name.Replace("_normal", "");
9749 this.IconNameToolStripMenuItem.Text = name;
9750 this.IconNameToolStripMenuItem.Enabled = true;
9754 this.IconNameToolStripMenuItem.Enabled = false;
9755 this.IconNameToolStripMenuItem.Text = Properties.Resources.ContextMenuStrip3_OpeningText1;
9760 this.IconNameToolStripMenuItem.Enabled = false;
9761 this.IconNameToolStripMenuItem.Text = Properties.Resources.ContextMenuStrip3_OpeningText1;
9763 if (this.IconCache.TryGetFromCache(_curPost.ImageUrl) != null)
9765 this.SaveIconPictureToolStripMenuItem.Enabled = true;
9769 this.SaveIconPictureToolStripMenuItem.Enabled = false;
9774 this.IconNameToolStripMenuItem.Enabled = false;
9775 this.SaveIconPictureToolStripMenuItem.Enabled = false;
9776 this.IconNameToolStripMenuItem.Text = Properties.Resources.ContextMenuStrip3_OpeningText1;
9781 this.IconNameToolStripMenuItem.Enabled = false;
9782 this.SaveIconPictureToolStripMenuItem.Enabled = false;
9783 this.IconNameToolStripMenuItem.Text = Properties.Resources.ContextMenuStrip3_OpeningText2;
9785 if (NameLabel.Tag != null)
9787 string id = (string)NameLabel.Tag;
9788 if (id == tw.Username)
9790 FollowToolStripMenuItem.Enabled = false;
9791 UnFollowToolStripMenuItem.Enabled = false;
9792 ShowFriendShipToolStripMenuItem.Enabled = false;
9793 ShowUserStatusToolStripMenuItem.Enabled = true;
9794 SearchPostsDetailNameToolStripMenuItem.Enabled = true;
9795 SearchAtPostsDetailNameToolStripMenuItem.Enabled = false;
9796 ListManageUserContextToolStripMenuItem3.Enabled = true;
9800 FollowToolStripMenuItem.Enabled = true;
9801 UnFollowToolStripMenuItem.Enabled = true;
9802 ShowFriendShipToolStripMenuItem.Enabled = true;
9803 ShowUserStatusToolStripMenuItem.Enabled = true;
9804 SearchPostsDetailNameToolStripMenuItem.Enabled = true;
9805 SearchAtPostsDetailNameToolStripMenuItem.Enabled = true;
9806 ListManageUserContextToolStripMenuItem3.Enabled = true;
9811 FollowToolStripMenuItem.Enabled = false;
9812 UnFollowToolStripMenuItem.Enabled = false;
9813 ShowFriendShipToolStripMenuItem.Enabled = false;
9814 ShowUserStatusToolStripMenuItem.Enabled = false;
9815 SearchPostsDetailNameToolStripMenuItem.Enabled = false;
9816 SearchAtPostsDetailNameToolStripMenuItem.Enabled = false;
9817 ListManageUserContextToolStripMenuItem3.Enabled = false;
9821 private void IconNameToolStripMenuItem_Click(object sender, EventArgs e)
9823 if (_curPost == null) return;
9824 string name = _curPost.ImageUrl;
9825 OpenUriAsync(name.Remove(name.LastIndexOf("_normal"), 7)); // "_normal".Length
9828 private void SaveOriginalSizeIconPictureToolStripMenuItem_Click(object sender, EventArgs e)
9830 if (_curPost == null) return;
9831 string name = _curPost.ImageUrl;
9832 name = Path.GetFileNameWithoutExtension(name.Substring(name.LastIndexOf('/')));
9834 this.SaveFileDialog1.FileName = name.Substring(0, name.Length - 8); // "_normal".Length + 1
9836 if (this.SaveFileDialog1.ShowDialog() == DialogResult.OK)
9842 private void SaveIconPictureToolStripMenuItem_Click(object sender, EventArgs e)
9844 if (_curPost == null) return;
9845 string name = _curPost.ImageUrl;
9847 this.SaveFileDialog1.FileName = name.Substring(name.LastIndexOf('/') + 1);
9849 if (this.SaveFileDialog1.ShowDialog() == DialogResult.OK)
9853 using (Image orgBmp = new Bitmap(IconCache.TryGetFromCache(name).Image))
9855 using (Bitmap bmp2 = new Bitmap(orgBmp.Size.Width, orgBmp.Size.Height))
9857 using (Graphics g = Graphics.FromImage(bmp2))
9859 g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
9860 g.DrawImage(orgBmp, 0, 0, orgBmp.Size.Width, orgBmp.Size.Height);
9862 bmp2.Save(this.SaveFileDialog1.FileName);
9868 //処理中にキャッシュアウトする可能性あり
9873 private void SplitContainer2_Panel2_Resize(object sender, EventArgs e)
9875 this.StatusText.Multiline = this.SplitContainer2.Panel2.Height > this.SplitContainer2.Panel2MinSize + 2;
9876 MultiLineMenuItem.Checked = this.StatusText.Multiline;
9877 _modifySettingLocal = true;
9880 private void StatusText_MultilineChanged(object sender, EventArgs e)
9882 if (this.StatusText.Multiline)
9883 this.StatusText.ScrollBars = ScrollBars.Vertical;
9885 this.StatusText.ScrollBars = ScrollBars.None;
9887 _modifySettingLocal = true;
9890 private void MultiLineMenuItem_Click(object sender, EventArgs e)
9893 StatusText.Multiline = MultiLineMenuItem.Checked;
9894 _cfgLocal.StatusMultiline = MultiLineMenuItem.Checked;
9895 if (MultiLineMenuItem.Checked)
9897 if (SplitContainer2.Height - _mySpDis2 - SplitContainer2.SplitterWidth < 0)
9898 SplitContainer2.SplitterDistance = 0;
9900 SplitContainer2.SplitterDistance = SplitContainer2.Height - _mySpDis2 - SplitContainer2.SplitterWidth;
9904 SplitContainer2.SplitterDistance = SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth;
9906 _modifySettingLocal = true;
9909 private bool UrlConvert(MyCommon.UrlConverter Converter_Type)
9911 //t.coで投稿時自動短縮する場合は、外部サービスでの短縮禁止
9912 //if (SettingDialog.UrlConvertAuto && SettingDialog.ShortenTco) return;
9914 //Converter_Type=Nicomsの場合は、nicovideoのみ短縮する
9915 //参考資料 RFC3986 Uniform Resource Identifier (URI): Generic Syntax
9916 //Appendix A. Collected ABNF for URI
9917 //http://www.ietf.org/rfc/rfc3986.txt
9921 const string nico = @"^https?://[a-z]+\.(nicovideo|niconicommons|nicolive)\.jp/[a-z]+/[a-z0-9]+$";
9923 if (StatusText.SelectionLength > 0)
9925 string tmp = StatusText.SelectedText;
9926 // httpから始まらない場合、ExcludeStringで指定された文字列で始まる場合は対象としない
9927 if (tmp.StartsWith("http"))
9929 // 文字列が選択されている場合はその文字列について処理
9931 //nico.ms使用、nicovideoにマッチしたら変換
9932 if (SettingDialog.Nicoms && Regex.IsMatch(tmp, nico))
9934 result = nicoms.Shorten(tmp);
9936 else if (Converter_Type != MyCommon.UrlConverter.Nicoms)
9938 //短縮URL変換 日本語を含むかもしれないのでURLエンコードする
9939 result = ShortUrl.Make(Converter_Type, tmp);
9940 if (result.Equals("Can't convert"))
9942 StatusLabel.Text = result.Insert(0, Converter_Type.ToString() + ":");
9951 if (!string.IsNullOrEmpty(result))
9953 urlUndo undotmp = new urlUndo();
9955 StatusText.Select(StatusText.Text.IndexOf(tmp, StringComparison.Ordinal), tmp.Length);
9956 StatusText.SelectedText = result;
9959 undotmp.Before = tmp;
9960 undotmp.After = result;
9962 if (urlUndoBuffer == null)
9964 urlUndoBuffer = new List<urlUndo>();
9965 UrlUndoToolStripMenuItem.Enabled = true;
9968 urlUndoBuffer.Add(undotmp);
9974 const string url = @"(?<before>(?:[^\""':!=]|^|\:))" +
9975 @"(?<url>(?<protocol>https?://)" +
9976 @"(?<domain>(?:[\.-]|[^\p{P}\s])+\.[a-z]{2,}(?::[0-9]+)?)" +
9977 @"(?<path>/[a-z0-9!*//();:&=+$/%#\-_.,~@]*[a-z0-9)=#/]?)?" +
9978 @"(?<query>\?[a-z0-9!*//();:&=+$/%#\-_.,~@?]*[a-z0-9_&=#/])?)";
9979 // 正規表現にマッチしたURL文字列をtinyurl化
9980 foreach (Match mt in Regex.Matches(StatusText.Text, url, RegexOptions.IgnoreCase))
9982 if (StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal) == -1) continue;
9983 string tmp = mt.Result("${url}");
9984 if (tmp.StartsWith("w", StringComparison.OrdinalIgnoreCase)) tmp = "http://" + tmp;
9985 urlUndo undotmp = new urlUndo();
9988 StatusText.Select(StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length);
9990 //nico.ms使用、nicovideoにマッチしたら変換
9991 if (SettingDialog.Nicoms && Regex.IsMatch(tmp, nico))
9993 result = nicoms.Shorten(tmp);
9995 else if (Converter_Type != MyCommon.UrlConverter.Nicoms)
9997 //短縮URL変換 日本語を含むかもしれないのでURLエンコードする
9998 result = ShortUrl.Make(Converter_Type, tmp);
9999 if (result.Equals("Can't convert"))
10001 StatusLabel.Text = result.Insert(0, Converter_Type.ToString() + ":");
10010 if (!string.IsNullOrEmpty(result))
10012 StatusText.Select(StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length);
10013 StatusText.SelectedText = result;
10015 undotmp.Before = mt.Result("${url}");
10016 undotmp.After = result;
10018 if (urlUndoBuffer == null)
10020 urlUndoBuffer = new List<urlUndo>();
10021 UrlUndoToolStripMenuItem.Enabled = true;
10024 urlUndoBuffer.Add(undotmp);
10032 private void doUrlUndo()
10034 if (urlUndoBuffer != null)
10036 string tmp = StatusText.Text;
10037 foreach (urlUndo data in urlUndoBuffer)
10039 tmp = tmp.Replace(data.After, data.Before);
10041 StatusText.Text = tmp;
10042 urlUndoBuffer = null;
10043 UrlUndoToolStripMenuItem.Enabled = false;
10044 StatusText.SelectionStart = 0;
10045 StatusText.SelectionLength = 0;
10049 private void TinyURLToolStripMenuItem_Click(object sender, EventArgs e)
10051 UrlConvert(MyCommon.UrlConverter.TinyUrl);
10054 private void IsgdToolStripMenuItem_Click(object sender, EventArgs e)
10056 UrlConvert(MyCommon.UrlConverter.Isgd);
10059 private void TwurlnlToolStripMenuItem_Click(object sender, EventArgs e)
10061 UrlConvert(MyCommon.UrlConverter.Twurl);
10064 private void UxnuMenuItem_Click(object sender, EventArgs e)
10066 UrlConvert(MyCommon.UrlConverter.Uxnu);
10069 private void UrlConvertAutoToolStripMenuItem_Click(object sender, EventArgs e)
10071 if (!UrlConvert(SettingDialog.AutoShortUrlFirst))
10073 MyCommon.UrlConverter svc = SettingDialog.AutoShortUrlFirst;
10074 Random rnd = new Random();
10075 // 前回使用した短縮URLサービス以外を選択する
10078 svc = (MyCommon.UrlConverter)rnd.Next(System.Enum.GetNames(typeof(MyCommon.UrlConverter)).Length);
10080 while (svc == SettingDialog.AutoShortUrlFirst || svc == MyCommon.UrlConverter.Nicoms || svc == MyCommon.UrlConverter.Unu);
10085 private void UrlUndoToolStripMenuItem_Click(object sender, EventArgs e)
10090 private void NewPostPopMenuItem_CheckStateChanged(object sender, EventArgs e)
10092 this.NotifyFileMenuItem.Checked = ((ToolStripMenuItem)sender).Checked;
10093 this.NewPostPopMenuItem.Checked = this.NotifyFileMenuItem.Checked;
10094 _cfgCommon.NewAllPop = NewPostPopMenuItem.Checked;
10095 _modifySettingCommon = true;
10098 private void ListLockMenuItem_CheckStateChanged(object sender, EventArgs e)
10100 ListLockMenuItem.Checked = ((ToolStripMenuItem)sender).Checked;
10101 this.LockListFileMenuItem.Checked = ListLockMenuItem.Checked;
10102 _cfgCommon.ListLock = ListLockMenuItem.Checked;
10103 _modifySettingCommon = true;
10106 private void MenuStrip1_MenuActivate(object sender, EventArgs e)
10108 // フォーカスがメニューに移る (MenuStrip1.Tag フラグを立てる)
10109 MenuStrip1.Tag = new Object();
10110 MenuStrip1.Select(); // StatusText がフォーカスを持っている場合 Leave が発生
10113 private void MenuStrip1_MenuDeactivate(object sender, EventArgs e)
10115 if (this.Tag != null) // 設定された戻り先へ遷移
10117 if (this.Tag == this.ListTab.SelectedTab)
10118 ((Control)this.ListTab.SelectedTab.Tag).Select();
10120 ((Control)this.Tag).Select();
10122 else // 戻り先が指定されていない (初期状態) 場合はタブに遷移
10124 if (ListTab.SelectedIndex > -1 && ListTab.SelectedTab.HasChildren)
10126 this.Tag = ListTab.SelectedTab.Tag;
10127 ((Control)this.Tag).Select();
10130 // フォーカスがメニューに遷移したかどうかを表すフラグを降ろす
10131 MenuStrip1.Tag = null;
10134 private void MyList_ColumnReordered(object sender, ColumnReorderedEventArgs e)
10136 DetailsListView lst = (DetailsListView)sender;
10137 if (_cfgLocal == null) return;
10141 _cfgLocal.Width1 = lst.Columns[0].Width;
10142 _cfgLocal.Width3 = lst.Columns[1].Width;
10146 int[] darr = new int[lst.Columns.Count];
10147 for (int i = 0; i < lst.Columns.Count; i++)
10149 darr[lst.Columns[i].DisplayIndex] = i;
10151 MyCommon.MoveArrayItem(darr, e.OldDisplayIndex, e.NewDisplayIndex);
10153 for (int i = 0; i < lst.Columns.Count; i++)
10158 _cfgLocal.DisplayIndex1 = i;
10161 _cfgLocal.DisplayIndex2 = i;
10164 _cfgLocal.DisplayIndex3 = i;
10167 _cfgLocal.DisplayIndex4 = i;
10170 _cfgLocal.DisplayIndex5 = i;
10173 _cfgLocal.DisplayIndex6 = i;
10176 _cfgLocal.DisplayIndex7 = i;
10179 _cfgLocal.DisplayIndex8 = i;
10183 _cfgLocal.Width1 = lst.Columns[0].Width;
10184 _cfgLocal.Width2 = lst.Columns[1].Width;
10185 _cfgLocal.Width3 = lst.Columns[2].Width;
10186 _cfgLocal.Width4 = lst.Columns[3].Width;
10187 _cfgLocal.Width5 = lst.Columns[4].Width;
10188 _cfgLocal.Width6 = lst.Columns[5].Width;
10189 _cfgLocal.Width7 = lst.Columns[6].Width;
10190 _cfgLocal.Width8 = lst.Columns[7].Width;
10192 _modifySettingLocal = true;
10193 _isColumnChanged = true;
10196 private void MyList_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e)
10198 DetailsListView lst = (DetailsListView)sender;
10199 if (_cfgLocal == null) return;
10202 if (_cfgLocal.Width1 != lst.Columns[0].Width)
10204 _cfgLocal.Width1 = lst.Columns[0].Width;
10205 _modifySettingLocal = true;
10206 _isColumnChanged = true;
10208 if (_cfgLocal.Width3 != lst.Columns[1].Width)
10210 _cfgLocal.Width3 = lst.Columns[1].Width;
10211 _modifySettingLocal = true;
10212 _isColumnChanged = true;
10217 if (_cfgLocal.Width1 != lst.Columns[0].Width)
10219 _cfgLocal.Width1 = lst.Columns[0].Width;
10220 _modifySettingLocal = true;
10221 _isColumnChanged = true;
10223 if (_cfgLocal.Width2 != lst.Columns[1].Width)
10225 _cfgLocal.Width2 = lst.Columns[1].Width;
10226 _modifySettingLocal = true;
10227 _isColumnChanged = true;
10229 if (_cfgLocal.Width3 != lst.Columns[2].Width)
10231 _cfgLocal.Width3 = lst.Columns[2].Width;
10232 _modifySettingLocal = true;
10233 _isColumnChanged = true;
10235 if (_cfgLocal.Width4 != lst.Columns[3].Width)
10237 _cfgLocal.Width4 = lst.Columns[3].Width;
10238 _modifySettingLocal = true;
10239 _isColumnChanged = true;
10241 if (_cfgLocal.Width5 != lst.Columns[4].Width)
10243 _cfgLocal.Width5 = lst.Columns[4].Width;
10244 _modifySettingLocal = true;
10245 _isColumnChanged = true;
10247 if (_cfgLocal.Width6 != lst.Columns[5].Width)
10249 _cfgLocal.Width6 = lst.Columns[5].Width;
10250 _modifySettingLocal = true;
10251 _isColumnChanged = true;
10253 if (_cfgLocal.Width7 != lst.Columns[6].Width)
10255 _cfgLocal.Width7 = lst.Columns[6].Width;
10256 _modifySettingLocal = true;
10257 _isColumnChanged = true;
10259 if (_cfgLocal.Width8 != lst.Columns[7].Width)
10261 _cfgLocal.Width8 = lst.Columns[7].Width;
10262 _modifySettingLocal = true;
10263 _isColumnChanged = true;
10266 // 非表示の時にColumnChangedが呼ばれた場合はForm初期化処理中なので保存しない
10269 // SaveConfigsLocal();
10273 public string WebBrowser_GetSelectionText(ref WebBrowser ComponentInstance)
10275 //発言詳細で「選択文字列をコピー」を行う
10276 //WebBrowserコンポーネントのインスタンスを渡す
10277 Type typ = ComponentInstance.ActiveXInstance.GetType();
10278 object _SelObj = typ.InvokeMember("selection", BindingFlags.GetProperty, null, ComponentInstance.Document.DomDocument, null);
10279 object _objRange = _SelObj.GetType().InvokeMember("createRange", BindingFlags.InvokeMethod, null, _SelObj, null);
10280 return (string)_objRange.GetType().InvokeMember("text", BindingFlags.GetProperty, null, _objRange, null);
10283 private void SelectionCopyContextMenuItem_Click(object sender, EventArgs e)
10286 string _selText = WebBrowser_GetSelectionText(ref PostBrowser);
10289 Clipboard.SetDataObject(_selText, false, 5, 100);
10291 catch (Exception ex)
10293 MessageBox.Show(ex.Message);
10297 private void doSearchToolStrip(string url)
10299 //発言詳細で「選択文字列で検索」(選択文字列取得)
10300 string _selText = WebBrowser_GetSelectionText(ref PostBrowser);
10302 if (_selText != null)
10304 if (url == Properties.Resources.SearchItem4Url)
10307 AddNewTabForSearch(_selText);
10311 string tmp = string.Format(url, Uri.EscapeUriString(_selText));
10316 private void SelectionAllContextMenuItem_Click(object sender, EventArgs e)
10319 PostBrowser.Document.ExecCommand("SelectAll", false, null);
10322 private void SearchWikipediaContextMenuItem_Click(object sender, EventArgs e)
10324 doSearchToolStrip(Properties.Resources.SearchItem1Url);
10327 private void SearchGoogleContextMenuItem_Click(object sender, EventArgs e)
10329 doSearchToolStrip(Properties.Resources.SearchItem2Url);
10332 private void SearchPublicSearchContextMenuItem_Click(object sender, EventArgs e)
10334 doSearchToolStrip(Properties.Resources.SearchItem4Url);
10337 private void UrlCopyContextMenuItem_Click(object sender, EventArgs e)
10341 MatchCollection mc = Regex.Matches(this.PostBrowser.DocumentText, @"<a[^>]*href=""(?<url>" + this._postBrowserStatusText.Replace(".", @"\.") + @")""[^>]*title=""(?<title>https?://[^""]+)""", RegexOptions.IgnoreCase);
10342 foreach (Match m in mc)
10344 if (m.Groups["url"].Value == this._postBrowserStatusText)
10346 Clipboard.SetDataObject(m.Groups["title"].Value, false, 5, 100);
10352 Clipboard.SetDataObject(this._postBrowserStatusText, false, 5, 100);
10354 //Clipboard.SetDataObject(this._postBrowserStatusText, false, 5, 100);
10356 catch (Exception ex)
10358 MessageBox.Show(ex.Message);
10362 private void ContextMenuPostBrowser_Opening(object ender, CancelEventArgs e)
10364 // URLコピーの項目の表示/非表示
10365 if (PostBrowser.StatusText.StartsWith("http"))
10367 this._postBrowserStatusText = PostBrowser.StatusText;
10368 string name = GetUserId();
10369 UrlCopyContextMenuItem.Enabled = true;
10372 FollowContextMenuItem.Enabled = true;
10373 RemoveContextMenuItem.Enabled = true;
10374 FriendshipContextMenuItem.Enabled = true;
10375 ShowUserStatusContextMenuItem.Enabled = true;
10376 SearchPostsDetailToolStripMenuItem.Enabled = true;
10377 IdFilterAddMenuItem.Enabled = true;
10378 ListManageUserContextToolStripMenuItem.Enabled = true;
10379 SearchAtPostsDetailToolStripMenuItem.Enabled = true;
10383 FollowContextMenuItem.Enabled = false;
10384 RemoveContextMenuItem.Enabled = false;
10385 FriendshipContextMenuItem.Enabled = false;
10386 ShowUserStatusContextMenuItem.Enabled = false;
10387 SearchPostsDetailToolStripMenuItem.Enabled = false;
10388 IdFilterAddMenuItem.Enabled = false;
10389 ListManageUserContextToolStripMenuItem.Enabled = false;
10390 SearchAtPostsDetailToolStripMenuItem.Enabled = false;
10393 if (Regex.IsMatch(this._postBrowserStatusText, @"^https?://twitter.com/search\?q=%23"))
10394 UseHashtagMenuItem.Enabled = true;
10396 UseHashtagMenuItem.Enabled = false;
10400 this._postBrowserStatusText = "";
10401 UrlCopyContextMenuItem.Enabled = false;
10402 FollowContextMenuItem.Enabled = false;
10403 RemoveContextMenuItem.Enabled = false;
10404 FriendshipContextMenuItem.Enabled = false;
10405 ShowUserStatusContextMenuItem.Enabled = false;
10406 SearchPostsDetailToolStripMenuItem.Enabled = false;
10407 SearchAtPostsDetailToolStripMenuItem.Enabled = false;
10408 UseHashtagMenuItem.Enabled = false;
10409 IdFilterAddMenuItem.Enabled = false;
10410 ListManageUserContextToolStripMenuItem.Enabled = false;
10412 // 文字列選択されていないときは選択文字列関係の項目を非表示に
10413 string _selText = WebBrowser_GetSelectionText(ref PostBrowser);
10414 if (_selText == null)
10416 SelectionSearchContextMenuItem.Enabled = false;
10417 SelectionCopyContextMenuItem.Enabled = false;
10418 SelectionTranslationToolStripMenuItem.Enabled = false;
10422 SelectionSearchContextMenuItem.Enabled = true;
10423 SelectionCopyContextMenuItem.Enabled = true;
10424 SelectionTranslationToolStripMenuItem.Enabled = true;
10426 //発言内に自分以外のユーザーが含まれてればフォロー状態全表示を有効に
10427 MatchCollection ma = Regex.Matches(this.PostBrowser.DocumentText, @"href=""https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?""");
10428 bool fAllFlag = false;
10429 foreach (Match mu in ma)
10431 if (mu.Result("${ScreenName}").ToLower() != tw.Username.ToLower())
10437 this.FriendshipAllMenuItem.Enabled = fAllFlag;
10439 if (_curPost == null)
10440 TranslationToolStripMenuItem.Enabled = false;
10442 TranslationToolStripMenuItem.Enabled = true;
10447 private void CurrentTabToolStripMenuItem_Click(object sender, EventArgs e)
10449 //発言詳細の選択文字列で現在のタブを検索
10450 string _selText = WebBrowser_GetSelectionText(ref PostBrowser);
10452 if (_selText != null)
10454 SearchDialog.SWord = _selText;
10455 SearchDialog.CheckCaseSensitive = false;
10456 SearchDialog.CheckRegex = false;
10458 DoTabSearch(SearchDialog.SWord,
10459 SearchDialog.CheckCaseSensitive,
10460 SearchDialog.CheckRegex,
10461 SEARCHTYPE.NextSearch);
10465 private void SplitContainer2_SplitterMoved(object sender, SplitterEventArgs e)
10467 if (StatusText.Multiline) _mySpDis2 = StatusText.Height;
10468 _modifySettingLocal = true;
10471 private void TweenMain_DragDrop(object sender, DragEventArgs e)
10473 if (e.Data.GetDataPresent(DataFormats.FileDrop))
10475 ImageSelectionPanel.Visible = true;
10476 ImageSelectionPanel.Enabled = true;
10477 TimelinePanel.Visible = false;
10478 TimelinePanel.Enabled = false;
10479 ImagefilePathText.Text = ((string[])e.Data.GetData(DataFormats.FileDrop, false))[0];
10480 ImageFromSelectedFile();
10482 this.BringToFront();
10483 StatusText.Focus();
10485 else if (e.Data.GetDataPresent(DataFormats.StringFormat))
10487 string data = (string)e.Data.GetData(DataFormats.StringFormat, true);
10488 if (data != null) StatusText.Text += data;
10492 private void TweenMain_DragOver(object sender, DragEventArgs e)
10494 if (e.Data.GetDataPresent(DataFormats.FileDrop))
10496 string filename = ((string[])e.Data.GetData(DataFormats.FileDrop, false))[0];
10497 FileInfo fl = new FileInfo(filename);
10498 string ext = fl.Extension;
10500 if (!string.IsNullOrEmpty(this.ImageService) && this.pictureService[this.ImageService].CheckValidFilesize(ext, fl.Length))
10502 e.Effect = DragDropEffects.Copy;
10505 foreach (string svc in ImageServiceCombo.Items)
10507 if (string.IsNullOrEmpty(svc)) continue;
10508 if (this.pictureService[svc].CheckValidFilesize(ext, fl.Length))
10510 ImageServiceCombo.SelectedItem = svc;
10511 e.Effect = DragDropEffects.Copy;
10515 e.Effect = DragDropEffects.None;
10517 else if (e.Data.GetDataPresent(DataFormats.StringFormat))
10519 e.Effect = DragDropEffects.Copy;
10523 e.Effect = DragDropEffects.None;
10527 public bool IsNetworkAvailable()
10530 nw = MyCommon.IsNetworkAvailable();
10531 _myStatusOnline = nw;
10535 public Task OpenUriAsync(string UriString)
10537 return Task.Factory.StartNew(() =>
10539 string myPath = UriString;
10543 var configBrowserPath = SettingDialog.BrowserPath;
10544 if (!string.IsNullOrEmpty(configBrowserPath))
10546 if (configBrowserPath.StartsWith("\"") && configBrowserPath.Length > 2 && configBrowserPath.IndexOf("\"", 2) > -1)
10548 int sep = configBrowserPath.IndexOf("\"", 2);
10549 string browserPath = configBrowserPath.Substring(1, sep - 1);
10551 if (sep < configBrowserPath.Length - 1)
10553 arg = configBrowserPath.Substring(sep + 1);
10555 myPath = arg + " " + myPath;
10556 System.Diagnostics.Process.Start(browserPath, myPath);
10560 System.Diagnostics.Process.Start(configBrowserPath, myPath);
10565 System.Diagnostics.Process.Start(myPath);
10570 //MessageBox.Show("ブラウザの起動に失敗、またはタイムアウトしました。" + ex.ToString());
10575 private void ListTabSelect(TabPage _tab)
10579 this.PurgeListViewItemCache();
10582 _curList = (DetailsListView)_tab.Tag;
10583 if (_curList.SelectedIndices.Count > 0)
10585 _curItemIndex = _curList.SelectedIndices[0];
10586 _curPost = GetCurTabPost(_curItemIndex);
10590 _curItemIndex = -1;
10594 _anchorPost = null;
10595 _anchorFlag = false;
10599 ((DetailsListView)_tab.Tag).Columns[1].Text = ColumnText[2];
10603 for (int i = 0; i < _curList.Columns.Count; i++)
10605 ((DetailsListView)_tab.Tag).Columns[i].Text = ColumnText[i];
10610 private void ListTab_Selecting(object sender, TabControlCancelEventArgs e)
10612 ListTabSelect(e.TabPage);
10615 private void SelectListItem(DetailsListView LView, int Index)
10618 Rectangle bnd = new Rectangle();
10620 if (LView.FocusedItem != null)
10622 bnd = LView.FocusedItem.Bounds;
10628 LView.SelectedIndices.Clear();
10630 while (LView.SelectedIndices.Count > 0);
10631 LView.Items[Index].Selected = true;
10632 //LView.SelectedIndices.Add(Index);
10633 LView.Items[Index].Focused = true;
10635 if (flg) LView.Invalidate(bnd);
10638 private void SelectListItem(DetailsListView LView , int[] Index, int FocusedIndex)
10641 Rectangle bnd = new Rectangle();
10643 if (LView.FocusedItem != null)
10645 bnd = LView.FocusedItem.Bounds;
10650 if (Index != null && !(Index.Length == 1 && Index[0] == -1))
10654 LView.SelectedIndices.Clear();
10656 while (LView.SelectedIndices.Count > 0);
10657 foreach (int idx in Index)
10659 if (idx > -1 && LView.VirtualListSize > idx)
10661 LView.SelectedIndices.Add(idx);
10662 if (fIdx == -1) fIdx = idx;
10666 if (FocusedIndex > -1 && LView.VirtualListSize > FocusedIndex)
10668 LView.Items[FocusedIndex].Focused = true;
10670 else if (fIdx > -1)
10672 LView.Items[fIdx].Focused = true;
10674 if (flg) LView.Invalidate(bnd);
10677 private void RunAsync(GetWorkerArg args)
10679 BackgroundWorker bw = null;
10680 if (args.type != MyCommon.WORKERTYPE.Follower)
10682 for (int i = 0; i < _bw.Length; i++)
10684 if (_bw[i] != null && !_bw[i].IsBusy)
10692 for (int i = 0; i < _bw.Length; i++)
10694 if (_bw[i] == null)
10696 _bw[i] = new BackgroundWorker();
10698 bw.WorkerReportsProgress = true;
10699 bw.WorkerSupportsCancellation = true;
10700 bw.DoWork += GetTimelineWorker_DoWork;
10701 bw.ProgressChanged += GetTimelineWorker_ProgressChanged;
10702 bw.RunWorkerCompleted += GetTimelineWorker_RunWorkerCompleted;
10710 if (_bwFollower == null)
10712 _bwFollower = new BackgroundWorker();
10714 bw.WorkerReportsProgress = true;
10715 bw.WorkerSupportsCancellation = true;
10716 bw.DoWork += GetTimelineWorker_DoWork;
10717 bw.ProgressChanged += GetTimelineWorker_ProgressChanged;
10718 bw.RunWorkerCompleted += GetTimelineWorker_RunWorkerCompleted;
10722 if (_bwFollower.IsBusy == false)
10726 if (bw == null) return;
10728 bw.RunWorkerAsync(args);
10731 private void StartUserStream()
10733 tw.NewPostFromStream += tw_NewPostFromStream;
10734 tw.UserStreamStarted += tw_UserStreamStarted;
10735 tw.UserStreamStopped += tw_UserStreamStopped;
10736 tw.PostDeleted += tw_PostDeleted;
10737 tw.UserStreamEventReceived += tw_UserStreamEventArrived;
10739 MenuItemUserStream.Text = "&UserStream ■";
10740 MenuItemUserStream.Enabled = true;
10741 StopToolStripMenuItem.Text = "&Start";
10742 StopToolStripMenuItem.Enabled = true;
10743 if (SettingDialog.UserstreamStartup) tw.StartUserStream();
10746 private void TweenMain_Shown(object sender, EventArgs e)
10750 PostBrowser.Url = new Uri("about:blank");
10751 PostBrowser.DocumentText = ""; //発言詳細部初期化
10757 NotifyIcon1.Visible = true;
10759 if (this.IsNetworkAvailable())
10761 GetTimeline(MyCommon.WORKERTYPE.BlockIds, 0, 0, "");
10762 if (SettingDialog.StartupFollowers)
10764 GetTimeline(MyCommon.WORKERTYPE.Follower, 0, 0, "");
10766 GetTimeline(MyCommon.WORKERTYPE.Configuration, 0, 0, "");
10768 _waitTimeline = true;
10769 GetTimeline(MyCommon.WORKERTYPE.Timeline, 1, 1, "");
10771 GetTimeline(MyCommon.WORKERTYPE.Reply, 1, 1, "");
10773 GetTimeline(MyCommon.WORKERTYPE.DirectMessegeRcv, 1, 1, "");
10774 if (SettingDialog.GetFav)
10777 GetTimeline(MyCommon.WORKERTYPE.Favorites, 1, 1, "");
10779 _waitPubSearch = true;
10780 GetTimeline(MyCommon.WORKERTYPE.PublicSearch, 1, 0, ""); //tabname="":全タブ
10781 _waitUserTimeline = true;
10782 GetTimeline(MyCommon.WORKERTYPE.UserTimeline, 1, 0, ""); //tabname="":全タブ
10784 GetTimeline(MyCommon.WORKERTYPE.List, 1, 0, ""); //tabname="":全タブ
10787 while (IsInitialRead() && !MyCommon._endingFlag)
10789 System.Threading.Thread.Sleep(100);
10790 Application.DoEvents();
10793 if (j > 1200) break; // 120秒間初期処理が終了しなかったら強制的に打ち切る
10796 if (MyCommon._endingFlag)
10802 if (MyCommon._endingFlag) return;
10804 if (ApplicationSettings.VersionInfoUrl != null)
10806 //バージョンチェック(引数:起動時チェックの場合はtrue・・・チェック結果のメッセージを表示しない)
10807 if (SettingDialog.StartupVersion)
10808 CheckNewVersion(true);
10812 // ApplicationSetting.cs の設定により更新チェックが無効化されている場合
10813 this.VerUpMenuItem.Enabled = false;
10814 this.VerUpMenuItem.Available = false;
10815 this.ToolStripSeparator16.Available = false; // VerUpMenuItem の一つ上にあるセパレータ
10819 if (!tw.GetFollowersSuccess && SettingDialog.StartupFollowers)
10820 GetTimeline(MyCommon.WORKERTYPE.Follower, 0, 0, "");
10823 if (SettingDialog.TwitterConfiguration.PhotoSizeLimit == 0)
10824 GetTimeline(MyCommon.WORKERTYPE.Configuration, 0, 0, "");
10826 // 権限チェック read/write権限(xAuthで取得したトークン)の場合は再認証を促す
10827 if (MyCommon.TwitterApiInfo.AccessLevel == TwitterApiAccessLevel.ReadWrite)
10829 MessageBox.Show(Properties.Resources.ReAuthorizeText);
10830 SettingStripMenuItem_Click(null, null);
10837 TimerTimeline.Enabled = true;
10840 private bool IsInitialRead()
10842 return _waitTimeline || _waitReply || _waitDm || _waitFav || _waitPubSearch || _waitUserTimeline || _waitLists;
10845 private void doGetFollowersMenu()
10847 GetTimeline(MyCommon.WORKERTYPE.Follower, 1, 0, "");
10848 DispSelectedPost(true);
10851 private void GetFollowersAllToolStripMenuItem_Click(object sender, EventArgs e)
10853 doGetFollowersMenu();
10856 private void doReTweetUnofficial()
10859 if (this.ExistCurrentPost)
10861 if (_curPost.IsDm ||
10862 !StatusText.Enabled) return;
10864 if (_curPost.IsProtect)
10866 MessageBox.Show("Protected.");
10869 string rtdata = _curPost.Text;
10870 rtdata = CreateRetweetUnofficial(rtdata);
10872 StatusText.Text = "RT @" + _curPost.ScreenName + ": " + WebUtility.HtmlDecode(rtdata);
10874 StatusText.SelectionStart = 0;
10875 StatusText.Focus();
10879 private void ReTweetStripMenuItem_Click(object sender, EventArgs e)
10881 doReTweetUnofficial();
10884 private void doReTweetOfficial(bool isConfirm)
10887 if (this.ExistCurrentPost)
10889 if (_curPost.IsProtect)
10891 MessageBox.Show("Protected.");
10892 _DoFavRetweetFlags = false;
10895 if (_curList.SelectedIndices.Count > 15)
10897 MessageBox.Show(Properties.Resources.RetweetLimitText);
10898 _DoFavRetweetFlags = false;
10901 else if (_curList.SelectedIndices.Count > 1)
10903 string QuestionText = Properties.Resources.RetweetQuestion2;
10904 if (_DoFavRetweetFlags) QuestionText = Properties.Resources.FavoriteRetweetQuestionText1;
10905 switch (MessageBox.Show(QuestionText, "Retweet", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question))
10907 case DialogResult.Cancel:
10908 case DialogResult.No:
10909 _DoFavRetweetFlags = false;
10915 if (_curPost.IsDm || _curPost.IsMe)
10917 _DoFavRetweetFlags = false;
10920 if (!SettingDialog.RetweetNoConfirm)
10922 string Questiontext = Properties.Resources.RetweetQuestion1;
10923 if (_DoFavRetweetFlags) Questiontext = Properties.Resources.FavoritesRetweetQuestionText2;
10924 if (isConfirm && MessageBox.Show(Questiontext, "Retweet", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
10926 _DoFavRetweetFlags = false;
10931 GetWorkerArg args = new GetWorkerArg();
10932 args.ids = new List<long>();
10933 args.sIds = new List<long>();
10934 args.tName = _curTab.Text;
10935 args.type = MyCommon.WORKERTYPE.Retweet;
10936 foreach (int idx in _curList.SelectedIndices)
10938 PostClass post = GetCurTabPost(idx);
10939 if (!post.IsMe && !post.IsProtect && !post.IsDm) args.ids.Add(post.StatusId);
10945 private void ReTweetOriginalStripMenuItem_Click(object sender, EventArgs e)
10947 doReTweetOfficial(true);
10950 private void FavoritesRetweetOriginal()
10952 if (!this.ExistCurrentPost) return;
10953 _DoFavRetweetFlags = true;
10954 doReTweetOfficial(true);
10955 if (_DoFavRetweetFlags)
10957 _DoFavRetweetFlags = false;
10958 FavoriteChange(true, false);
10962 private void FavoritesRetweetUnofficial()
10964 if (this.ExistCurrentPost && !_curPost.IsDm)
10966 _DoFavRetweetFlags = true;
10967 FavoriteChange(true);
10968 if (!_curPost.IsProtect && _DoFavRetweetFlags)
10970 _DoFavRetweetFlags = false;
10971 doReTweetUnofficial();
10976 private string CreateRetweetUnofficial(string status)
10978 // Twitterにより省略されているURLを含むaタグをキャプチャしてリンク先URLへ置き換える
10979 status = Regex.Replace(status, @"<a target=""_self"" href=""(?<url>[^""]+)"" title=""(?<title>[^""]+)""[^>]*>(?<link>[^<]+)</a>", "${title}");
10981 //その他のリンク(@IDなど)を置き換える
10982 status = Regex.Replace(status, @"@<a target=""_self"" href=""https?://twitter.com/(#!/)?(?<url>[^""]+)""[^>]*>(?<link>[^<]+)</a>", "@${url}");
10984 status = Regex.Replace(status, @"<a target=""_self"" href=""(?<url>[^""]+)""[^>]*>(?<link>[^<]+)</a>", "${link}");
10986 if (StatusText.Multiline)
10987 status = Regex.Replace(status, @"(\r\n|\n|\r)?<br>", "\r\n", RegexOptions.IgnoreCase | RegexOptions.Multiline);
10989 status = Regex.Replace(status, @"(\r\n|\n|\r)?<br>", " ", RegexOptions.IgnoreCase | RegexOptions.Multiline);
10992 _reply_to_name = "";
10993 status = status.Replace(" ", " ");
10998 private void DumpPostClassToolStripMenuItem_Click(object sender, EventArgs e)
11000 if (_curPost != null)
11001 DispSelectedPost(true);
11004 private void MenuItemHelp_DropDownOpening(object sender, EventArgs e)
11006 if (MyCommon.DebugBuild || MyCommon.IsKeyDown(Keys.CapsLock, Keys.Control, Keys.Shift))
11007 DebugModeToolStripMenuItem.Visible = true;
11009 DebugModeToolStripMenuItem.Visible = false;
11012 private void ToolStripMenuItemUrlAutoShorten_CheckedChanged(object sender, EventArgs e)
11014 SettingDialog.UrlConvertAuto = ToolStripMenuItemUrlAutoShorten.Checked;
11017 private void ContextMenuPostMode_Opening(object sender, CancelEventArgs e)
11019 ToolStripMenuItemUrlAutoShorten.Checked = SettingDialog.UrlConvertAuto;
11022 private void TraceOutToolStripMenuItem_Click(object sender, EventArgs e)
11024 if (TraceOutToolStripMenuItem.Checked)
11025 MyCommon.TraceFlag = true;
11027 MyCommon.TraceFlag = false;
11030 private void TweenMain_Deactivate(object sender, EventArgs e)
11032 //画面が非アクティブになったら、発言欄の背景色をデフォルトへ
11033 this.StatusText_Leave(StatusText, System.EventArgs.Empty);
11036 private void TabRenameMenuItem_Click(object sender, EventArgs e)
11038 if (string.IsNullOrEmpty(_rclickTabName)) return;
11039 TabRename(ref _rclickTabName);
11042 private void BitlyToolStripMenuItem_Click(object sender, EventArgs e)
11044 UrlConvert(MyCommon.UrlConverter.Bitly);
11047 private void JmpToolStripMenuItem_Click(object sender, EventArgs e)
11049 UrlConvert(MyCommon.UrlConverter.Jmp);
11053 private void GetApiInfo_Dowork(object sender, DoWorkEventArgs e)
11055 if (HttpTwitter.API11Enabled)
11056 e.Result = tw.GetInfoApi11();
11058 e.Result = tw.GetInfoApi10();
11061 private void ApiUsageInfoMenuItem_Click(object sender, EventArgs e)
11063 StringBuilder tmp = new StringBuilder();
11065 using (FormInfo dlg = new FormInfo(this, Properties.Resources.ApiInfo6, GetApiInfo_Dowork))
11069 TwitterApiAccessLevel? accessLevel = null;
11070 ApiLimit timelineLimit = null, mediaLimit = null;
11072 if (dlg.Result is TwitterApiStatus)
11074 var result = (TwitterApiStatus)dlg.Result;
11076 accessLevel = result.AccessLevel;
11077 timelineLimit = result.AccessLimit;
11078 mediaLimit = result.MediaUploadLimit;
11080 else if (dlg.Result is TwitterApiStatus11)
11082 var result = (TwitterApiStatus11)dlg.Result;
11084 accessLevel = result.AccessLevel;
11085 timelineLimit = result.AccessLimit["/statuses/home_timeline"];
11086 mediaLimit = result.MediaUploadLimit;
11089 if (accessLevel != null)
11091 tmp.AppendLine(Properties.Resources.ApiInfo1 + timelineLimit.AccessLimitCount);
11092 tmp.AppendLine(Properties.Resources.ApiInfo2 + timelineLimit.AccessLimitRemain);
11093 tmp.AppendLine(Properties.Resources.ApiInfo3 + timelineLimit.AccessLimitResetDate);
11094 tmp.AppendLine(Properties.Resources.ApiInfo7 + (tw.UserStreamEnabled ? Properties.Resources.Enable : Properties.Resources.Disable));
11097 tmp.AppendLine(Properties.Resources.ApiInfo8 + accessLevel);
11098 SetStatusLabelUrl();
11101 tmp.AppendLine(Properties.Resources.ApiInfo9 + (mediaLimit == null ? Properties.Resources.ApiInfo91 : mediaLimit.AccessLimitCount.ToString()));
11102 tmp.AppendLine(Properties.Resources.ApiInfo10 + (mediaLimit == null ? Properties.Resources.ApiInfo91 : mediaLimit.AccessLimitRemain.ToString()));
11103 tmp.AppendLine(Properties.Resources.ApiInfo11 + (mediaLimit == null ? Properties.Resources.ApiInfo91 : mediaLimit.AccessLimitResetDate.ToString()));
11107 tmp.Append(Properties.Resources.ApiInfo5);
11111 MessageBox.Show(tmp.ToString(), Properties.Resources.ApiInfo4, MessageBoxButtons.OK, MessageBoxIcon.Information);
11114 private void FollowCommandMenuItem_Click(object sender, EventArgs e)
11117 if (_curPost != null) id = _curPost.ScreenName;
11121 private void FollowCommand_DoWork(object sender, DoWorkEventArgs e)
11123 FollowRemoveCommandArgs arg = (FollowRemoveCommandArgs)e.Argument;
11124 e.Result = arg.tw.PostFollowCommand(arg.id);
11127 private void FollowCommand(string id)
11129 using (InputTabName inputName = new InputTabName())
11131 inputName.FormTitle = "Follow";
11132 inputName.FormDescription = Properties.Resources.FRMessage1;
11133 inputName.TabName = id;
11134 if (inputName.ShowDialog() == DialogResult.OK &&
11135 !string.IsNullOrEmpty(inputName.TabName.Trim()))
11137 FollowRemoveCommandArgs arg = new FollowRemoveCommandArgs();
11139 arg.id = inputName.TabName.Trim();
11140 using (FormInfo _info = new FormInfo(this, Properties.Resources.FollowCommandText1,
11141 FollowCommand_DoWork,
11145 _info.ShowDialog();
11146 string ret = (string)_info.Result;
11147 if (!string.IsNullOrEmpty(ret))
11148 MessageBox.Show(Properties.Resources.FRMessage2 + ret);
11150 MessageBox.Show(Properties.Resources.FRMessage3);
11156 private void RemoveCommandMenuItem_Click(object sender, EventArgs e)
11159 if (_curPost != null) id = _curPost.ScreenName;
11160 RemoveCommand(id, false);
11163 private class FollowRemoveCommandArgs
11169 private void RemoveCommand_DoWork(object sender , DoWorkEventArgs e)
11171 FollowRemoveCommandArgs arg = (FollowRemoveCommandArgs)e.Argument;
11172 e.Result = arg.tw.PostRemoveCommand(arg.id);
11175 private void RemoveCommand(string id, bool skipInput)
11177 FollowRemoveCommandArgs arg = new FollowRemoveCommandArgs();
11182 using (InputTabName inputName = new InputTabName())
11184 inputName.FormTitle = "Unfollow";
11185 inputName.FormDescription = Properties.Resources.FRMessage1;
11186 inputName.TabName = id;
11187 if (inputName.ShowDialog() == DialogResult.OK &&
11188 !string.IsNullOrEmpty(inputName.TabName.Trim()))
11191 arg.id = inputName.TabName.Trim();
11200 using (FormInfo _info = new FormInfo(this, Properties.Resources.RemoveCommandText1,
11201 RemoveCommand_DoWork,
11205 _info.ShowDialog();
11206 string ret = (string)_info.Result;
11207 if (!string.IsNullOrEmpty(ret))
11208 MessageBox.Show(Properties.Resources.FRMessage2 + ret);
11210 MessageBox.Show(Properties.Resources.FRMessage3);
11214 private void FriendshipMenuItem_Click(object sender, EventArgs e)
11217 if (_curPost != null)
11218 id = _curPost.ScreenName;
11220 ShowFriendship(id);
11223 private class ShowFriendshipArgs
11226 public class FriendshipInfo
11228 public string id = "";
11229 public bool isFollowing = false;
11230 public bool isFollowed = false;
11231 public bool isError = false;
11232 public FriendshipInfo(string id)
11237 public List<FriendshipInfo> ids = new List<FriendshipInfo>();
11240 private void ShowFriendship_DoWork(object sender, DoWorkEventArgs e)
11242 ShowFriendshipArgs arg = (ShowFriendshipArgs)e.Argument;
11243 string result = "";
11244 foreach (ShowFriendshipArgs.FriendshipInfo fInfo in arg.ids)
11246 string rt = arg.tw.GetFriendshipInfo(fInfo.id, ref fInfo.isFollowing, ref fInfo.isFollowed);
11247 if (!string.IsNullOrEmpty(rt))
11249 if (string.IsNullOrEmpty(result)) result = rt;
11250 fInfo.isError = true;
11256 private void ShowFriendship(string id)
11258 ShowFriendshipArgs args = new ShowFriendshipArgs();
11260 using (InputTabName inputName = new InputTabName())
11262 inputName.FormTitle = "Show Friendships";
11263 inputName.FormDescription = Properties.Resources.FRMessage1;
11264 inputName.TabName = id;
11265 if (inputName.ShowDialog() == DialogResult.OK &&
11266 !string.IsNullOrEmpty(inputName.TabName.Trim()))
11269 args.ids.Add(new ShowFriendshipArgs.FriendshipInfo(inputName.TabName.Trim()));
11270 using (FormInfo _info = new FormInfo(this, Properties.Resources.ShowFriendshipText1,
11271 ShowFriendship_DoWork,
11275 _info.ShowDialog();
11276 ret = (string)_info.Result;
11278 string result = "";
11279 if (string.IsNullOrEmpty(ret))
11281 if (args.ids[0].isFollowing)
11283 result = Properties.Resources.GetFriendshipInfo1 + System.Environment.NewLine;
11287 result = Properties.Resources.GetFriendshipInfo2 + System.Environment.NewLine;
11289 if (args.ids[0].isFollowed)
11291 result += Properties.Resources.GetFriendshipInfo3;
11295 result += Properties.Resources.GetFriendshipInfo4;
11297 result = args.ids[0].id + Properties.Resources.GetFriendshipInfo5 + System.Environment.NewLine + result;
11303 MessageBox.Show(result);
11308 private void ShowFriendship(string[] ids)
11310 foreach (string id in ids)
11313 ShowFriendshipArgs args = new ShowFriendshipArgs();
11315 args.ids.Add(new ShowFriendshipArgs.FriendshipInfo(id.Trim()));
11316 using (FormInfo _info = new FormInfo(this, Properties.Resources.ShowFriendshipText1,
11317 ShowFriendship_DoWork,
11321 _info.ShowDialog();
11322 ret = (string)_info.Result;
11324 string result = "";
11325 ShowFriendshipArgs.FriendshipInfo fInfo = args.ids[0];
11327 if (string.IsNullOrEmpty(ret))
11330 if (fInfo.isFollowing)
11332 ff += Properties.Resources.GetFriendshipInfo1;
11336 ff += Properties.Resources.GetFriendshipInfo2;
11339 ff += System.Environment.NewLine + " ";
11340 if (fInfo.isFollowed)
11342 ff += Properties.Resources.GetFriendshipInfo3;
11346 ff += Properties.Resources.GetFriendshipInfo4;
11348 result += fInfo.id + Properties.Resources.GetFriendshipInfo5 + System.Environment.NewLine + ff;
11349 if (fInfo.isFollowing)
11351 if (MessageBox.Show(
11352 Properties.Resources.GetFriendshipInfo7 + System.Environment.NewLine + result, Properties.Resources.GetFriendshipInfo8,
11353 MessageBoxButtons.YesNo,
11354 MessageBoxIcon.Question,
11355 MessageBoxDefaultButton.Button2) == DialogResult.Yes)
11357 RemoveCommand(fInfo.id, true);
11362 MessageBox.Show(result);
11367 MessageBox.Show(ret);
11372 private void OwnStatusMenuItem_Click(object sender, EventArgs e)
11374 doShowUserStatus(tw.Username, false);
11375 //if (!string.IsNullOrEmpty(tw.UserInfoXml))
11377 // doShowUserStatus(tw.Username, false);
11381 // MessageBox.Show(Properties.Resources.ShowYourProfileText1, "Your status", MessageBoxButtons.OK, MessageBoxIcon.Information);
11386 // TwitterIDでない固定文字列を調べる(文字列検証のみ 実際に取得はしない)
11387 // URLから切り出した文字列を渡す
11389 public bool IsTwitterId(string name)
11391 if (SettingDialog.TwitterConfiguration.NonUsernamePaths == null || SettingDialog.TwitterConfiguration.NonUsernamePaths.Length == 0)
11392 return !Regex.Match(name, @"^(about|jobs|tos|privacy|who_to_follow|download|messages)$", RegexOptions.IgnoreCase).Success;
11394 return !SettingDialog.TwitterConfiguration.NonUsernamePaths.Contains(name.ToLower());
11397 private string GetUserId()
11399 Match m = Regex.Match(this._postBrowserStatusText, @"^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?$");
11400 if (m.Success && IsTwitterId(m.Result("${ScreenName}")))
11401 return m.Result("${ScreenName}");
11406 private void FollowContextMenuItem_Click(object sender, EventArgs e)
11408 string name = GetUserId();
11409 if (name != null) FollowCommand(name);
11412 private void RemoveContextMenuItem_Click(object sender, EventArgs e)
11414 string name = GetUserId();
11415 if (name != null) RemoveCommand(name, false);
11418 private void FriendshipContextMenuItem_Click(object sender, EventArgs e)
11420 string name = GetUserId();
11421 if (name != null) ShowFriendship(name);
11424 private void FriendshipAllMenuItem_Click(object sender, EventArgs e)
11426 MatchCollection ma = Regex.Matches(this.PostBrowser.DocumentText, @"href=""https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?""");
11427 List<string> ids = new List<string>();
11428 foreach (Match mu in ma)
11430 if (mu.Result("${ScreenName}").ToLower() != tw.Username.ToLower())
11432 ids.Add(mu.Result("${ScreenName}"));
11435 ShowFriendship(ids.ToArray());
11438 private void ShowUserStatusContextMenuItem_Click(object sender, EventArgs e)
11440 string name = GetUserId();
11441 if (name != null) ShowUserStatus(name);
11444 private void SearchPostsDetailToolStripMenuItem_Click(object sender, EventArgs e)
11446 string name = GetUserId();
11447 if (name != null) AddNewTabForUserTimeline(name);
11450 private void SearchAtPostsDetailToolStripMenuItem_Click(object sender, EventArgs e)
11452 string name = GetUserId();
11453 if (name != null) AddNewTabForSearch("@" + name);
11456 private void IdeographicSpaceToSpaceToolStripMenuItem_Click(object sender, EventArgs e)
11458 _modifySettingCommon = true;
11461 private void ToolStripFocusLockMenuItem_CheckedChanged(object sender, EventArgs e)
11463 _modifySettingCommon = true;
11466 private void doQuote()
11470 if (this.ExistCurrentPost)
11472 if (_curPost.IsDm ||
11473 !StatusText.Enabled) return;
11475 if (_curPost.IsProtect)
11477 MessageBox.Show("Protected.");
11480 string rtdata = _curPost.Text;
11481 rtdata = CreateRetweetUnofficial(rtdata);
11483 StatusText.Text = " QT @" + _curPost.ScreenName + ": " + WebUtility.HtmlDecode(rtdata);
11484 if (_curPost.RetweetedId == 0)
11486 _reply_to_id = _curPost.StatusId;
11490 _reply_to_id = _curPost.RetweetedId;
11492 _reply_to_name = _curPost.ScreenName;
11494 StatusText.SelectionStart = 0;
11495 StatusText.Focus();
11499 private void QuoteStripMenuItem_Click(object sender, EventArgs e) // Handles QuoteStripMenuItem.Click, QtOpMenuItem.Click
11504 private void SearchButton_Click(object sender, EventArgs e)
11507 Control pnl = ((Control)sender).Parent;
11508 if (pnl == null) return;
11509 string tbName = pnl.Parent.Text;
11510 TabClass tb = _statuses.Tabs[tbName];
11511 ComboBox cmb = (ComboBox)pnl.Controls["comboSearch"];
11512 ComboBox cmbLang = (ComboBox)pnl.Controls["comboLang"];
11513 ComboBox cmbusline = (ComboBox)pnl.Controls["comboUserline"];
11514 cmb.Text = cmb.Text.Trim();
11515 // 検索式演算子 OR についてのみ大文字しか認識しないので強制的に大文字とする
11516 bool Quote = false;
11517 StringBuilder buf = new StringBuilder();
11518 char[] c = cmb.Text.ToCharArray();
11519 for (int cnt = 0; cnt < cmb.Text.Length; cnt++)
11521 if (cnt > cmb.Text.Length - 4)
11523 buf.Append(cmb.Text.Substring(cnt));
11532 if (!Quote && cmb.Text.Substring(cnt, 4).Equals(" or ", StringComparison.OrdinalIgnoreCase))
11534 buf.Append(" OR ");
11539 buf.Append(c[cnt]);
11541 cmb.Text = buf.ToString();
11543 tb.SearchWords = cmb.Text;
11544 tb.SearchLang = cmbLang.Text;
11545 if (string.IsNullOrEmpty(cmb.Text))
11547 ((DetailsListView)ListTab.SelectedTab.Tag).Focus();
11551 if (tb.IsQueryChanged())
11553 int idx = ((ComboBox)pnl.Controls["comboSearch"]).Items.IndexOf(tb.SearchWords);
11554 if (idx > -1) ((ComboBox)pnl.Controls["comboSearch"]).Items.RemoveAt(idx);
11555 ((ComboBox)pnl.Controls["comboSearch"]).Items.Insert(0, tb.SearchWords);
11556 cmb.Text = tb.SearchWords;
11558 DetailsListView lst = (DetailsListView)pnl.Parent.Tag;
11559 lst.VirtualListSize = 0;
11561 _statuses.ClearTabIds(tbName);
11562 SaveConfigsTabs(); //検索条件の保存
11565 GetTimeline(MyCommon.WORKERTYPE.PublicSearch, 1, 0, tbName);
11566 ((DetailsListView)ListTab.SelectedTab.Tag).Focus();
11569 private void RefreshMoreStripMenuItem_Click(object sender, EventArgs e)
11575 private void UndoRemoveTabMenuItem_Click(object sender, EventArgs e)
11577 if (_statuses.RemovedTab.Count == 0)
11579 MessageBox.Show("There isn't removed tab.", "Undo", MessageBoxButtons.OK, MessageBoxIcon.Information);
11584 TabClass tb = _statuses.RemovedTab.Pop();
11585 string renamed = tb.TabName;
11586 for (int i = 1; i < int.MaxValue; i++)
11588 if (!_statuses.ContainsTab(renamed)) break;
11589 renamed = tb.TabName + "(" + i.ToString() + ")";
11591 tb.TabName = renamed;
11592 _statuses.Tabs.Add(renamed, tb);
11593 AddNewTab(renamed, false, tb.TabType, tb.ListInfo);
11594 ListTab.SelectedIndex = ListTab.TabPages.Count - 1;
11599 private void doMoveToRTHome()
11601 if (_curList.SelectedIndices.Count > 0)
11603 PostClass post = GetCurTabPost(_curList.SelectedIndices[0]);
11604 if (post.RetweetedId > 0)
11606 OpenUriAsync("http://twitter.com/" + GetCurTabPost(_curList.SelectedIndices[0]).RetweetedBy);
11611 private void MoveToRTHomeMenuItem_Click(object sender, EventArgs e)
11616 private void IdFilterAddMenuItem_Click(object sender, EventArgs e)
11618 string name = GetUserId();
11624 if (_curList.SelectedIndices.Count == 0) return;
11627 if (!SelectTab(out tabName)) return;
11631 MoveOrCopy(ref mv, ref mk);
11633 FiltersClass fc = new FiltersClass();
11634 fc.NameFilter = name;
11635 fc.SearchBoth = true;
11638 fc.UseRegex = false;
11639 fc.SearchUrl = false;
11640 _statuses.Tabs[tabName].AddFilter(fc);
11644 this.Cursor = Cursors.WaitCursor;
11645 this.PurgeListViewItemCache();
11647 _curItemIndex = -1;
11648 _statuses.FilterAll();
11649 foreach (TabPage tb in ListTab.TabPages)
11651 ((DetailsListView)tb.Tag).VirtualListSize = _statuses.Tabs[tb.Text].AllCount;
11652 if (_statuses.Tabs[tb.Text].UnreadCount > 0)
11654 if (SettingDialog.TabIconDisp)
11659 if (SettingDialog.TabIconDisp)
11660 tb.ImageIndex = -1;
11663 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
11667 this.Cursor = Cursors.Default;
11673 private void ListManageUserContextToolStripMenuItem_Click(object sender, EventArgs e)
11677 ToolStripMenuItem menuItem = (ToolStripMenuItem)sender;
11679 if (menuItem.Owner == this.ContextMenuPostBrowser)
11681 user = GetUserId();
11682 if (user == null) return;
11684 else if (this._curPost != null)
11686 user = this._curPost.ScreenName;
11693 if (TabInformations.GetInstance().SubscribableLists.Count == 0)
11695 string res = this.tw.GetListsApi();
11697 if (!string.IsNullOrEmpty(res))
11699 MessageBox.Show("Failed to get lists. (" + res + ")");
11704 using (MyLists listSelectForm = new MyLists(user, this.tw))
11706 listSelectForm.ShowDialog(this);
11710 private void SearchControls_Enter(object sender, EventArgs e)
11712 Control pnl = (Control)sender;
11713 foreach (Control ctl in pnl.Controls)
11715 ctl.TabStop = true;
11719 private void SearchControls_Leave(object sender, EventArgs e)
11721 Control pnl = (Control)sender;
11722 foreach (Control ctl in pnl.Controls)
11724 ctl.TabStop = false;
11728 private void PublicSearchQueryMenuItem_Click(object sender, EventArgs e)
11730 if (ListTab.SelectedTab != null)
11732 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType != MyCommon.TabUsageType.PublicSearch) return;
11733 ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"].Focus();
11737 private void UseHashtagMenuItem_Click(object sender, EventArgs e)
11739 Match m = Regex.Match(this._postBrowserStatusText, @"^https?://twitter.com/search\?q=%23(?<hash>.+)$");
11742 HashMgr.SetPermanentHash("#" + m.Result("${hash}"));
11743 HashStripSplitButton.Text = HashMgr.UseHash;
11744 HashToggleMenuItem.Checked = true;
11745 HashToggleToolStripMenuItem.Checked = true;
11747 _modifySettingCommon = true;
11751 private void StatusLabel_DoubleClick(object sender, EventArgs e)
11753 MessageBox.Show(StatusLabel.TextHistory, "Logs", MessageBoxButtons.OK, MessageBoxIcon.None);
11756 private void HashManageMenuItem_Click(object sender, EventArgs e)
11758 DialogResult rslt = DialogResult.Cancel;
11761 rslt = HashMgr.ShowDialog();
11767 this.TopMost = SettingDialog.AlwaysTop;
11768 if (rslt == DialogResult.Cancel) return;
11769 if (!string.IsNullOrEmpty(HashMgr.UseHash))
11771 HashStripSplitButton.Text = HashMgr.UseHash;
11772 HashToggleMenuItem.Checked = true;
11773 HashToggleToolStripMenuItem.Checked = true;
11777 HashStripSplitButton.Text = "#[-]";
11778 HashToggleMenuItem.Checked = false;
11779 HashToggleToolStripMenuItem.Checked = false;
11781 //if (HashMgr.IsInsert && HashMgr.UseHash != "")
11783 // int sidx = StatusText.SelectionStart;
11784 // string hash = HashMgr.UseHash + " ";
11787 // if (StatusText.Text.Substring(sidx - 1, 1) != " ")
11788 // hash = " " + hash;
11790 // StatusText.Text = StatusText.Text.Insert(sidx, hash);
11791 // sidx += hash.Length;
11792 // StatusText.SelectionStart = sidx;
11793 // StatusText.Focus();
11795 _modifySettingCommon = true;
11796 this.StatusText_TextChanged(null, null);
11799 private void HashToggleMenuItem_Click(object sender, EventArgs e)
11801 HashMgr.ToggleHash();
11802 if (!string.IsNullOrEmpty(HashMgr.UseHash))
11804 HashStripSplitButton.Text = HashMgr.UseHash;
11805 HashToggleMenuItem.Checked = true;
11806 HashToggleToolStripMenuItem.Checked = true;
11810 HashStripSplitButton.Text = "#[-]";
11811 HashToggleMenuItem.Checked = false;
11812 HashToggleToolStripMenuItem.Checked = false;
11814 _modifySettingCommon = true;
11815 this.StatusText_TextChanged(null, null);
11818 private void HashStripSplitButton_ButtonClick(object sender, EventArgs e)
11820 HashToggleMenuItem_Click(null, null);
11823 private void MenuItemOperate_DropDownOpening(object sender, EventArgs e)
11825 if (ListTab.SelectedTab == null) return;
11826 if (_statuses == null || _statuses.Tabs == null || !_statuses.Tabs.ContainsKey(ListTab.SelectedTab.Text)) return;
11827 if (!this.ExistCurrentPost)
11829 this.ReplyOpMenuItem.Enabled = false;
11830 this.ReplyAllOpMenuItem.Enabled = false;
11831 this.DmOpMenuItem.Enabled = false;
11832 this.ShowProfMenuItem.Enabled = false;
11833 this.ShowUserTimelineToolStripMenuItem.Enabled = false;
11834 this.ListManageMenuItem.Enabled = false;
11835 this.OpenFavOpMenuItem.Enabled = false;
11836 this.CreateTabRuleOpMenuItem.Enabled = false;
11837 this.CreateIdRuleOpMenuItem.Enabled = false;
11838 this.ReadOpMenuItem.Enabled = false;
11839 this.UnreadOpMenuItem.Enabled = false;
11843 this.ReplyOpMenuItem.Enabled = true;
11844 this.ReplyAllOpMenuItem.Enabled = true;
11845 this.DmOpMenuItem.Enabled = true;
11846 this.ShowProfMenuItem.Enabled = true;
11847 this.ShowUserTimelineToolStripMenuItem.Enabled = true;
11848 this.ListManageMenuItem.Enabled = true;
11849 this.OpenFavOpMenuItem.Enabled = true;
11850 this.CreateTabRuleOpMenuItem.Enabled = true;
11851 this.CreateIdRuleOpMenuItem.Enabled = true;
11852 this.ReadOpMenuItem.Enabled = true;
11853 this.UnreadOpMenuItem.Enabled = true;
11856 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.DirectMessage || !this.ExistCurrentPost || _curPost.IsDm)
11858 this.FavOpMenuItem.Enabled = false;
11859 this.UnFavOpMenuItem.Enabled = false;
11860 this.OpenStatusOpMenuItem.Enabled = false;
11861 this.OpenFavotterOpMenuItem.Enabled = false;
11862 this.ShowRelatedStatusesMenuItem2.Enabled = false;
11863 this.RtOpMenuItem.Enabled = false;
11864 this.RtUnOpMenuItem.Enabled = false;
11865 this.QtOpMenuItem.Enabled = false;
11866 this.FavoriteRetweetMenuItem.Enabled = false;
11867 this.FavoriteRetweetUnofficialMenuItem.Enabled = false;
11868 if (this.ExistCurrentPost && _curPost.IsDm) this.DelOpMenuItem.Enabled = true;
11872 this.FavOpMenuItem.Enabled = true;
11873 this.UnFavOpMenuItem.Enabled = true;
11874 this.OpenStatusOpMenuItem.Enabled = true;
11875 this.OpenFavotterOpMenuItem.Enabled = true;
11876 this.ShowRelatedStatusesMenuItem2.Enabled = true; //PublicSearchの時問題出るかも
11880 this.RtOpMenuItem.Enabled = false;
11881 this.FavoriteRetweetMenuItem.Enabled = false;
11882 this.DelOpMenuItem.Enabled = true;
11886 this.DelOpMenuItem.Enabled = false;
11887 if (_curPost.IsProtect)
11889 this.RtOpMenuItem.Enabled = false;
11890 this.RtUnOpMenuItem.Enabled = false;
11891 this.QtOpMenuItem.Enabled = false;
11892 this.FavoriteRetweetMenuItem.Enabled = false;
11893 this.FavoriteRetweetUnofficialMenuItem.Enabled = false;
11897 this.RtOpMenuItem.Enabled = true;
11898 this.RtUnOpMenuItem.Enabled = true;
11899 this.QtOpMenuItem.Enabled = true;
11900 this.FavoriteRetweetMenuItem.Enabled = true;
11901 this.FavoriteRetweetUnofficialMenuItem.Enabled = true;
11906 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType != MyCommon.TabUsageType.Favorites)
11908 this.RefreshPrevOpMenuItem.Enabled = true;
11912 this.RefreshPrevOpMenuItem.Enabled = false;
11914 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.PublicSearch
11915 || !this.ExistCurrentPost
11916 || !(_curPost.InReplyToStatusId > 0))
11918 OpenRepSourceOpMenuItem.Enabled = false;
11922 OpenRepSourceOpMenuItem.Enabled = true;
11924 if (!this.ExistCurrentPost || string.IsNullOrEmpty(_curPost.RetweetedBy))
11926 OpenRterHomeMenuItem.Enabled = false;
11930 OpenRterHomeMenuItem.Enabled = true;
11934 private void MenuItemTab_DropDownOpening(object sender, EventArgs e)
11936 ContextMenuTabProperty_Opening(sender, null);
11939 public Twitter TwitterInstance
11944 private void SplitContainer3_SplitterMoved(object sender, SplitterEventArgs e)
11946 if (this.WindowState == FormWindowState.Normal && !_initialLayout)
11948 _mySpDis3 = SplitContainer3.SplitterDistance;
11949 _modifySettingLocal = true;
11953 private void MenuItemEdit_DropDownOpening(object sender, EventArgs e)
11955 if (_statuses.RemovedTab.Count == 0)
11957 UndoRemoveTabMenuItem.Enabled = false;
11961 UndoRemoveTabMenuItem.Enabled = true;
11963 if (ListTab.SelectedTab != null)
11965 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.PublicSearch)
11966 PublicSearchQueryMenuItem.Enabled = true;
11968 PublicSearchQueryMenuItem.Enabled = false;
11972 PublicSearchQueryMenuItem.Enabled = false;
11974 if (!this.ExistCurrentPost)
11976 this.CopySTOTMenuItem.Enabled = false;
11977 this.CopyURLMenuItem.Enabled = false;
11978 this.CopyUserIdStripMenuItem.Enabled = false;
11982 this.CopySTOTMenuItem.Enabled = true;
11983 this.CopyURLMenuItem.Enabled = true;
11984 this.CopyUserIdStripMenuItem.Enabled = true;
11985 if (_curPost.IsDm) this.CopyURLMenuItem.Enabled = false;
11986 if (_curPost.IsProtect) this.CopySTOTMenuItem.Enabled = false;
11990 private void NotifyIcon1_MouseMove(object sender, MouseEventArgs e)
11992 SetNotifyIconText();
11995 private void UserStatusToolStripMenuItem_Click(object sender, EventArgs e)
11998 if (_curPost != null)
12000 id = _curPost.ScreenName;
12002 ShowUserStatus(id);
12005 private class GetUserInfoArgs
12009 public TwitterDataModel.User user;
12012 private void GetUserInfo_DoWork(object sender, DoWorkEventArgs e)
12014 GetUserInfoArgs args = (GetUserInfoArgs)e.Argument;
12015 e.Result = args.tw.GetUserInfo(args.id, ref args.user);
12018 private void doShowUserStatus(string id, bool ShowInputDialog)
12020 TwitterDataModel.User user = null;
12021 GetUserInfoArgs args = new GetUserInfoArgs();
12022 if (ShowInputDialog)
12024 using (InputTabName inputName = new InputTabName())
12026 inputName.FormTitle = "Show UserStatus";
12027 inputName.FormDescription = Properties.Resources.FRMessage1;
12028 inputName.TabName = id;
12029 if (inputName.ShowDialog() == DialogResult.OK &&
12030 !string.IsNullOrEmpty(inputName.TabName.Trim()))
12032 id = inputName.TabName.Trim();
12036 using (FormInfo _info = new FormInfo(this, Properties.Resources.doShowUserStatusText1,
12037 GetUserInfo_DoWork,
12041 _info.ShowDialog();
12042 string ret = (string)_info.Result;
12043 if (string.IsNullOrEmpty(ret))
12044 doShowUserStatus(args.user);
12046 MessageBox.Show(ret);
12056 using (FormInfo _info = new FormInfo(this, Properties.Resources.doShowUserStatusText1,
12057 GetUserInfo_DoWork,
12061 _info.ShowDialog();
12062 string ret = (string)_info.Result;
12063 if (string.IsNullOrEmpty(ret))
12065 doShowUserStatus(args.user);
12069 MessageBox.Show(ret);
12075 private void doShowUserStatus(TwitterDataModel.User user)
12077 using (ShowUserInfo userinfo = new ShowUserInfo())
12079 userinfo.Owner = this;
12080 userinfo.User = user;
12081 userinfo.ShowDialog(this);
12083 this.BringToFront();
12087 private void ShowUserStatus(string id, bool ShowInputDialog)
12089 doShowUserStatus(id, ShowInputDialog);
12092 private void ShowUserStatus(string id)
12094 doShowUserStatus(id, true);
12097 private void FollowToolStripMenuItem_Click(object sender, EventArgs e)
12099 if (NameLabel.Tag != null)
12101 string id = (string)NameLabel.Tag;
12102 if (id != tw.Username)
12109 private void UnFollowToolStripMenuItem_Click(object sender, EventArgs e)
12111 if (NameLabel.Tag != null)
12113 string id = (string)NameLabel.Tag;
12114 if (id != tw.Username)
12116 RemoveCommand(id, false);
12121 private void ShowFriendShipToolStripMenuItem_Click(object sender, EventArgs e)
12123 if (NameLabel.Tag != null)
12125 string id = (string)NameLabel.Tag;
12126 if (id != tw.Username)
12128 ShowFriendship(id);
12133 private void ShowUserStatusToolStripMenuItem_Click(object sender, EventArgs e)
12135 if (NameLabel.Tag != null)
12137 string id = (string)NameLabel.Tag;
12138 ShowUserStatus(id, false);
12142 private void SearchPostsDetailNameToolStripMenuItem_Click(object sender, EventArgs e)
12144 if (NameLabel.Tag != null)
12146 string id = (string)NameLabel.Tag;
12147 AddNewTabForUserTimeline(id);
12151 private void SearchAtPostsDetailNameToolStripMenuItem_Click(object sender, EventArgs e)
12153 if (NameLabel.Tag != null)
12155 string id = (string)NameLabel.Tag;
12156 AddNewTabForSearch("@" + id);
12160 private void ShowProfileMenuItem_Click(object sender, EventArgs e)
12162 if (_curPost != null)
12164 ShowUserStatus(_curPost.ScreenName, false);
12168 private void GetRetweet_DoWork(object sender, DoWorkEventArgs e)
12173 if (_curPost.RetweetedId > 0)
12175 statusid = _curPost.RetweetedId;
12179 statusid = _curPost.StatusId;
12181 tw.GetStatus_Retweeted_Count(statusid, ref counter);
12183 e.Result = counter;
12186 private void RtCountMenuItem_Click(object sender, EventArgs e)
12188 if (this.ExistCurrentPost)
12190 using (FormInfo _info = new FormInfo(this, Properties.Resources.RtCountMenuItem_ClickText1,
12191 GetRetweet_DoWork))
12193 int retweet_count = 0;
12196 _info.ShowDialog();
12197 retweet_count = (int)_info.Result;
12198 if (retweet_count < 0)
12200 MessageBox.Show(Properties.Resources.RtCountText2);
12204 MessageBox.Show(retweet_count.ToString() + Properties.Resources.RtCountText1);
12210 private HookGlobalHotkey _hookGlobalHotkey;
12213 _hookGlobalHotkey = new HookGlobalHotkey(this);
12214 // この呼び出しは、Windows フォーム デザイナで必要です。
12215 InitializeComponent();
12217 // InitializeComponent() 呼び出しの後で初期化を追加します。
12219 this.SettingDialog.IntervalChanged += this.TimerInterval_Changed;
12220 this.TimerTimeline.Elapsed += this.TimerTimeline_Elapsed;
12221 this._hookGlobalHotkey.HotkeyPressed += _hookGlobalHotkey_HotkeyPressed;
12222 this.gh.NotifyClicked += GrowlHelper_Callback;
12224 this._apiGauge = new ToolStripAPIGauge();
12225 this._apiGauge.Click += (s, e) =>
12227 var api11Enabled = !HttpTwitter.API11Enabled;
12229 HttpTwitter.API11Enabled = api11Enabled;
12230 (s as ToolStripAPIGauge).API11Enabled = api11Enabled;
12233 MyCommon.TwitterApiInfo11.Reset();
12235 MyCommon.TwitterApiInfo.Reset();
12237 this.StatusStrip1.Items.Insert(2, this._apiGauge);
12239 this.ReplaceAppName();
12242 private void _hookGlobalHotkey_HotkeyPressed(object sender, KeyEventArgs e)
12244 if ((this.WindowState == FormWindowState.Normal || this.WindowState == FormWindowState.Maximized) && this.Visible && Form.ActiveForm == this)
12247 this.Visible = false;
12249 else if (Form.ActiveForm == null)
12251 this.Visible = true;
12252 if (this.WindowState == FormWindowState.Minimized) this.WindowState = FormWindowState.Normal;
12254 this.BringToFront();
12255 this.StatusText.Focus();
12259 private void UserPicture_MouseEnter(object sender, EventArgs e)
12261 this.UserPicture.Cursor = Cursors.Hand;
12264 private void UserPicture_MouseLeave(object sender, EventArgs e)
12266 this.UserPicture.Cursor = Cursors.Default;
12269 private void UserPicture_DoubleClick(object sender, EventArgs e)
12271 if (NameLabel.Tag != null)
12273 OpenUriAsync(MyCommon.TwitterUrl + NameLabel.Tag.ToString());
12277 private void SplitContainer2_MouseDoubleClick(object sender, MouseEventArgs e)
12279 this.MultiLineMenuItem.PerformClick();
12282 public PostClass CurPost
12284 get { return _curPost; }
12287 public bool IsPreviewEnable
12289 get { return SettingDialog.PreviewEnable; }
12293 private void ImageSelectMenuItem_Click(object sender, EventArgs e)
12295 if (ImageSelectionPanel.Visible == true)
12297 ImagefilePathText.CausesValidation = false;
12298 TimelinePanel.Visible = true;
12299 TimelinePanel.Enabled = true;
12300 ImageSelectionPanel.Visible = false;
12301 ImageSelectionPanel.Enabled = false;
12302 ((DetailsListView)ListTab.SelectedTab.Tag).Focus();
12303 ImagefilePathText.CausesValidation = true;
12307 ImageSelectionPanel.Visible = true;
12308 ImageSelectionPanel.Enabled = true;
12309 TimelinePanel.Visible = false;
12310 TimelinePanel.Enabled = false;
12311 ImagefilePathText.Focus();
12315 private void FilePickButton_Click(object sender, EventArgs e)
12317 if (string.IsNullOrEmpty(this.ImageService)) return;
12318 OpenFileDialog1.Filter = this.pictureService[this.ImageService].GetFileOpenDialogFilter();
12319 OpenFileDialog1.Title = Properties.Resources.PickPictureDialog1;
12320 OpenFileDialog1.FileName = "";
12324 this.AllowDrop = false;
12325 if (OpenFileDialog1.ShowDialog() == DialogResult.Cancel) return;
12329 this.AllowDrop = true;
12332 ImagefilePathText.Text = OpenFileDialog1.FileName;
12333 ImageFromSelectedFile();
12336 private void ImagefilePathText_Validating(object sender, CancelEventArgs e)
12338 if (ImageCancelButton.Focused)
12340 ImagefilePathText.CausesValidation = false;
12343 ImagefilePathText.Text = ImagefilePathText.Text.Trim();
12344 if (string.IsNullOrEmpty(ImagefilePathText.Text))
12346 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12347 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12351 ImageFromSelectedFile();
12355 private void ImageFromSelectedFile()
12359 if (string.IsNullOrEmpty(ImagefilePathText.Text.Trim()) || string.IsNullOrEmpty(this.ImageService))
12361 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12362 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12363 ImagefilePathText.Text = "";
12367 FileInfo fl = new FileInfo(ImagefilePathText.Text.Trim());
12368 if (!this.pictureService[this.ImageService].CheckValidExtension(fl.Extension))
12371 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12372 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12373 ImagefilePathText.Text = "";
12377 if (!this.pictureService[this.ImageService].CheckValidFilesize(fl.Extension, fl.Length))
12380 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12381 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12382 ImagefilePathText.Text = "";
12383 MessageBox.Show("File is too large.");
12387 switch (this.pictureService[this.ImageService].GetFileType(fl.Extension))
12389 case MyCommon.UploadFileType.Invalid:
12390 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12391 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12392 ImagefilePathText.Text = "";
12394 case MyCommon.UploadFileType.Picture:
12396 using (FileStream fs = new FileStream(ImagefilePathText.Text, FileMode.Open, FileAccess.Read))
12398 img = Image.FromStream(fs);
12400 ImageSelectedPicture.Image = (new HttpVarious()).CheckValidImage(
12404 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Picture;
12406 case MyCommon.UploadFileType.MultiMedia:
12407 ImageSelectedPicture.Image = Properties.Resources.MultiMediaImage;
12408 ImageSelectedPicture.Tag = MyCommon.UploadFileType.MultiMedia;
12411 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12412 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12413 ImagefilePathText.Text = "";
12417 catch (FileNotFoundException)
12419 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12420 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12421 ImagefilePathText.Text = "";
12422 MessageBox.Show("File not found.");
12426 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12427 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12428 ImagefilePathText.Text = "";
12429 MessageBox.Show("The type of this file is not image.");
12433 private void ImageSelection_KeyDown(object sender, KeyEventArgs e)
12435 if (e.KeyCode == Keys.Escape)
12437 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12438 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12439 TimelinePanel.Visible = true;
12440 TimelinePanel.Enabled = true;
12441 ImageSelectionPanel.Visible = false;
12442 ImageSelectionPanel.Enabled = false;
12443 ((DetailsListView)ListTab.SelectedTab.Tag).Focus();
12444 ImagefilePathText.CausesValidation = true;
12448 private void ImageSelection_KeyPress(object sender, KeyPressEventArgs e)
12450 if (Convert.ToInt32(e.KeyChar) == 0x1B)
12452 ImagefilePathText.CausesValidation = false;
12457 private void ImageSelection_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
12459 if (e.KeyCode == Keys.Escape)
12461 ImagefilePathText.CausesValidation = false;
12465 private void SetImageServiceCombo()
12468 if (ImageServiceCombo.SelectedIndex > -1) svc = ImageServiceCombo.SelectedItem.ToString();
12469 ImageServiceCombo.Items.Clear();
12470 ImageServiceCombo.Items.Add("TwitPic");
12471 ImageServiceCombo.Items.Add("img.ly");
12472 ImageServiceCombo.Items.Add("yfrog");
12473 ImageServiceCombo.Items.Add("lockerz");
12474 ImageServiceCombo.Items.Add("Twitter");
12476 if (string.IsNullOrEmpty(svc))
12478 ImageServiceCombo.SelectedIndex = 0;
12482 int idx = ImageServiceCombo.Items.IndexOf(svc);
12484 ImageServiceCombo.SelectedIndex = 0;
12486 ImageServiceCombo.SelectedIndex = idx;
12490 private string ImageService
12492 get { return (string)ImageServiceCombo.SelectedItem; }
12495 private void ImageCancelButton_Click(object sender, EventArgs e)
12497 ImagefilePathText.CausesValidation = false;
12498 TimelinePanel.Visible = true;
12499 TimelinePanel.Enabled = true;
12500 ImageSelectionPanel.Visible = false;
12501 ImageSelectionPanel.Enabled = false;
12502 ((DetailsListView)ListTab.SelectedTab.Tag).Focus();
12503 ImagefilePathText.CausesValidation = true;
12506 private void ImageServiceCombo_SelectedIndexChanged(object sender, EventArgs e)
12508 if (ImageSelectedPicture.Tag != null && !string.IsNullOrEmpty(this.ImageService))
12512 FileInfo fi = new FileInfo(ImagefilePathText.Text.Trim());
12513 if (!this.pictureService[this.ImageService].CheckValidFilesize(fi.Extension, fi.Length))
12515 ImagefilePathText.Text = "";
12516 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12517 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12523 _modifySettingCommon = true;
12524 SaveConfigsAll(false);
12525 if (this.ImageService == "Twitter")
12527 this.StatusText_TextChanged(null, null);
12533 private void ListManageToolStripMenuItem_Click(object sender, EventArgs e)
12535 using (ListManage form = new ListManage(tw))
12537 form.ShowDialog(this);
12541 public bool ModifySettingCommon
12543 set { _modifySettingCommon = value; }
12546 public bool ModifySettingLocal
12548 set { _modifySettingLocal = value; }
12551 public bool ModifySettingAtId
12553 set { _modifySettingAtId = value; }
12556 private void SourceLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
12558 string link = (string)SourceLinkLabel.Tag;
12559 if (!string.IsNullOrEmpty(link) && e.Button == MouseButtons.Left)
12561 OpenUriAsync(link);
12565 private void SourceLinkLabel_MouseEnter(object sender, EventArgs e)
12567 string link = (string)SourceLinkLabel.Tag;
12568 if (!string.IsNullOrEmpty(link))
12570 StatusLabelUrl.Text = link;
12574 private void SourceLinkLabel_MouseLeave(object sender, EventArgs e)
12576 SetStatusLabelUrl();
12579 private void MenuItemCommand_DropDownOpening(object sender, EventArgs e)
12581 if (this.ExistCurrentPost && !_curPost.IsDm)
12582 RtCountMenuItem.Enabled = true;
12584 RtCountMenuItem.Enabled = false;
12586 //if (SettingDialog.UrlConvertAuto && SettingDialog.ShortenTco)
12587 // TinyUrlConvertToolStripMenuItem.Enabled = false;
12589 // TinyUrlConvertToolStripMenuItem.Enabled = true;
12592 private void CopyUserIdStripMenuItem_Click(object sender, EventArgs e)
12597 private void CopyUserId()
12599 if (_curPost == null) return;
12600 string clstr = _curPost.ScreenName;
12603 Clipboard.SetDataObject(clstr, false, 5, 100);
12605 catch (Exception ex)
12607 MessageBox.Show(ex.Message);
12611 private void ShowRelatedStatusesMenuItem_Click(object sender, EventArgs e) // Handles ShowRelatedStatusesMenuItem.Click, ShowRelatedStatusesMenuItem2.Click
12613 TabClass backToTab = _curTab == null ? _statuses.Tabs[ListTab.SelectedTab.Text] : _statuses.Tabs[_curTab.Text];
12614 if (this.ExistCurrentPost && !_curPost.IsDm)
12616 //PublicSearchも除外した方がよい?
12617 if (_statuses.GetTabByType(MyCommon.TabUsageType.Related) == null)
12619 const string TabName = "Related Tweets";
12620 string tName = TabName;
12621 if (!this.AddNewTab(tName, false, MyCommon.TabUsageType.Related))
12623 for (int i = 2; i <= 100; i++)
12625 tName = TabName + i.ToString();
12626 if (this.AddNewTab(tName, false, MyCommon.TabUsageType.Related))
12628 _statuses.AddTab(tName, MyCommon.TabUsageType.Related, null);
12635 _statuses.AddTab(tName, MyCommon.TabUsageType.Related, null);
12637 _statuses.GetTabByName(tName).UnreadManage = false;
12638 _statuses.GetTabByName(tName).Notify = false;
12641 TabClass tb = _statuses.GetTabByType(MyCommon.TabUsageType.Related);
12642 tb.RelationTargetPost = _curPost;
12643 this.ClearTab(tb.TabName, false);
12644 for (int i = 0; i < ListTab.TabPages.Count; i++)
12646 if (tb.TabName == ListTab.TabPages[i].Text)
12648 ListTab.SelectedIndex = i;
12649 ListTabSelect(ListTab.TabPages[i]);
12654 GetTimeline(MyCommon.WORKERTYPE.Related, 1, 1, tb.TabName);
12658 private void CacheInfoMenuItem_Click(object sender, EventArgs e)
12660 StringBuilder buf = new StringBuilder();
12661 //buf.AppendFormat("キャッシュメモリ容量 : {0}bytes({1}MB)" + Environment.NewLine, IconCache.CacheMemoryLimit, ((ImageDictionary)IconCache).CacheMemoryLimit / 1048576);
12662 //buf.AppendFormat("物理メモリ使用割合 : {0}%" + Environment.NewLine, IconCache.PhysicalMemoryLimit);
12663 buf.AppendFormat("キャッシュエントリ保持数 : {0}" + Environment.NewLine, IconCache.CacheCount);
12664 buf.AppendFormat("キャッシュエントリ破棄数 : {0}" + Environment.NewLine, IconCache.CacheRemoveCount);
12665 MessageBox.Show(buf.ToString(), "アイコンキャッシュ使用状況");
12668 private void tw_UserIdChanged()
12670 this._modifySettingCommon = true;
12673 #region "Userstream"
12674 private bool _isActiveUserstream = false;
12676 private void tw_PostDeleted(long id)
12680 if (InvokeRequired && !IsDisposed)
12682 Invoke((Action) (() =>
12684 _statuses.RemovePostReserve(id);
12685 if (_curTab != null && _statuses.Tabs[_curTab.Text].Contains(id))
12687 this.PurgeListViewItemCache();
12688 ((DetailsListView)_curTab.Tag).Update();
12689 if (_curPost != null && _curPost.StatusId == id) DispSelectedPost(true);
12695 catch (ObjectDisposedException)
12699 catch (InvalidOperationException)
12705 private void tw_NewPostFromStream()
12707 if (SettingDialog.ReadOldPosts)
12709 _statuses.SetRead(); //新着時未読クリア
12712 int rsltAddCount = _statuses.DistributePosts();
12715 DateTime tm = DateTime.Now;
12716 if (_tlTimestamps.ContainsKey(tm))
12718 _tlTimestamps[tm] += rsltAddCount;
12722 _tlTimestamps.Add(tm, rsltAddCount);
12724 DateTime oneHour = DateTime.Now.Subtract(new TimeSpan(1, 0, 0));
12725 List<DateTime> keys = new List<DateTime>();
12727 foreach (DateTime key in _tlTimestamps.Keys)
12729 if (key.CompareTo(oneHour) < 0)
12732 _tlCount += _tlTimestamps[key];
12734 foreach (DateTime key in keys)
12736 _tlTimestamps.Remove(key);
12740 //Static DateTime before = Now;
12741 //if (before.Subtract(Now).Seconds > -5) return;
12745 if (SettingDialog.UserstreamPeriodInt > 0) return;
12749 if (InvokeRequired && !IsDisposed)
12751 Invoke(new Action<bool>(RefreshTimeline), true);
12755 catch (ObjectDisposedException)
12759 catch (InvalidOperationException)
12765 private void tw_UserStreamStarted()
12767 this._isActiveUserstream = true;
12770 if (InvokeRequired && !IsDisposed)
12772 Invoke(new MethodInvoker(tw_UserStreamStarted));
12776 catch (ObjectDisposedException)
12780 catch (InvalidOperationException)
12785 MenuItemUserStream.Text = "&UserStream ▶";
12786 MenuItemUserStream.Enabled = true;
12787 StopToolStripMenuItem.Text = "&Stop";
12788 StopToolStripMenuItem.Enabled = true;
12790 StatusLabel.Text = "UserStream Started.";
12793 private void tw_UserStreamStopped()
12795 this._isActiveUserstream = false;
12798 if (InvokeRequired && !IsDisposed)
12800 Invoke(new MethodInvoker(tw_UserStreamStopped));
12804 catch (ObjectDisposedException)
12808 catch (InvalidOperationException)
12813 MenuItemUserStream.Text = "&UserStream ■";
12814 MenuItemUserStream.Enabled = true;
12815 StopToolStripMenuItem.Text = "&Start";
12816 StopToolStripMenuItem.Enabled = true;
12818 StatusLabel.Text = "UserStream Stopped.";
12821 private void tw_UserStreamEventArrived(Twitter.FormattedEvent ev)
12825 if (InvokeRequired && !IsDisposed)
12827 Invoke(new Action<Twitter.FormattedEvent>(tw_UserStreamEventArrived), ev);
12831 catch (ObjectDisposedException)
12835 catch (InvalidOperationException)
12839 StatusLabel.Text = "Event: " + ev.Event;
12840 //if (ev.Event == "favorite")
12842 // NotifyFavorite(ev);
12845 if (ev.Event == "favorite" || ev.Event == "unfavorite")
12847 if (_curTab != null && _statuses.Tabs[_curTab.Text].Contains(ev.Id))
12849 this.PurgeListViewItemCache();
12850 ((DetailsListView)_curTab.Tag).Update();
12852 if (ev.Event == "unfavorite" && ev.Username.ToLower().Equals(tw.Username.ToLower()))
12854 RemovePostFromFavTab(new long[] {ev.Id});
12859 private void NotifyEvent(Twitter.FormattedEvent ev)
12862 if (BalloonRequired(ev))
12864 NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
12865 //if (SettingDialog.DispUsername) NotifyIcon1.BalloonTipTitle = tw.Username + " - "; else NotifyIcon1.BalloonTipTitle = "";
12866 //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [" + ev.Event.ToUpper() + "] by " + ((string)(!string.IsNullOrEmpty(ev.Username) ? ev.Username : ""), string);
12867 StringBuilder title = new StringBuilder();
12868 if (SettingDialog.DispUsername)
12870 title.Append(tw.Username);
12871 title.Append(" - ");
12877 title.Append(Application.ProductName);
12878 title.Append(" [");
12879 title.Append(ev.Event.ToUpper());
12880 title.Append("] by ");
12881 if (!string.IsNullOrEmpty(ev.Username))
12883 title.Append(ev.Username.ToString());
12887 //title.Append("");
12890 if (!string.IsNullOrEmpty(ev.Target))
12892 //NotifyIcon1.BalloonTipText = ev.Target;
12897 //NotifyIcon1.BalloonTipText = " ";
12900 //NotifyIcon1.ShowBalloonTip(500);
12901 if (SettingDialog.IsNotifyUseGrowl)
12903 gh.Notify(GrowlHelper.NotifyType.UserStreamEvent,
12904 ev.Id.ToString(), title.ToString(), text);
12908 NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
12909 NotifyIcon1.BalloonTipTitle = title.ToString();
12910 NotifyIcon1.BalloonTipText = text;
12911 NotifyIcon1.ShowBalloonTip(500);
12916 string snd = SettingDialog.EventSoundFile;
12917 if (!_initial && SettingDialog.PlaySound && !string.IsNullOrEmpty(snd))
12919 if ((ev.Eventtype & SettingDialog.EventNotifyFlag) != 0 && IsMyEventNotityAsEventType(ev))
12923 string dir = Application.StartupPath;
12924 if (Directory.Exists(Path.Combine(dir, "Sounds")))
12926 dir = Path.Combine(dir, "Sounds");
12928 using (SoundPlayer player = new SoundPlayer(Path.Combine(dir, snd)))
12940 private void StopToolStripMenuItem_Click(object sender, EventArgs e)
12942 MenuItemUserStream.Enabled = false;
12943 if (StopRefreshAllMenuItem.Checked)
12945 StopRefreshAllMenuItem.Checked = false;
12948 if (this._isActiveUserstream)
12950 tw.StopUserStream();
12954 tw.StartUserStream();
12958 private static string inputTrack = "";
12960 private void TrackToolStripMenuItem_Click(object sender, EventArgs e)
12962 if (TrackToolStripMenuItem.Checked)
12964 using (InputTabName inputForm = new InputTabName())
12966 inputForm.TabName = inputTrack;
12967 inputForm.FormTitle = "Input track word";
12968 inputForm.FormDescription = "Track word";
12969 if (inputForm.ShowDialog() != DialogResult.OK)
12971 TrackToolStripMenuItem.Checked = false;
12974 inputTrack = inputForm.TabName.Trim();
12976 if (!inputTrack.Equals(tw.TrackWord))
12978 tw.TrackWord = inputTrack;
12979 this._modifySettingCommon = true;
12980 TrackToolStripMenuItem.Checked = !string.IsNullOrEmpty(inputTrack);
12981 tw.ReconnectUserStream();
12987 tw.ReconnectUserStream();
12989 this._modifySettingCommon = true;
12992 private void AllrepliesToolStripMenuItem_Click(object sender, EventArgs e)
12994 tw.AllAtReply = AllrepliesToolStripMenuItem.Checked;
12995 this._modifySettingCommon = true;
12996 tw.ReconnectUserStream();
12999 private void EventViewerMenuItem_Click(object sender, EventArgs e)
13001 if (evtDialog == null || evtDialog.IsDisposed)
13004 evtDialog = new EventViewerDialog();
13005 evtDialog.Owner = this;
13007 Point pos = evtDialog.Location;
13008 pos.X = Convert.ToInt32(this.Location.X + this.Size.Width / 2 - evtDialog.Size.Width / 2);
13009 pos.Y = Convert.ToInt32(this.Location.Y + this.Size.Height / 2 - evtDialog.Size.Height / 2);
13010 evtDialog.Location = pos;
13012 evtDialog.EventSource = tw.StoredEvent;
13013 if (!evtDialog.Visible)
13015 evtDialog.Show(this);
13019 evtDialog.Activate();
13021 this.TopMost = this.SettingDialog.AlwaysTop;
13025 private void TweenRestartMenuItem_Click(object sender, EventArgs e)
13027 MyCommon._endingFlag = true;
13031 Application.Restart();
13035 MessageBox.Show("Failed to restart. Please run " + Application.ProductName + " manually.");
13039 private void OpenOwnFavedMenuItem_Click(object sender, EventArgs e)
13041 if (!string.IsNullOrEmpty(tw.Username)) OpenUriAsync(Properties.Resources.FavstarUrl + "users/" + tw.Username + "/recent");
13044 private void OpenOwnHomeMenuItem_Click(object sender, EventArgs e)
13046 OpenUriAsync(MyCommon.TwitterUrl + tw.Username);
13049 private void doTranslation(string str)
13051 Bing _bing = new Bing();
13053 if (string.IsNullOrEmpty(str)) return;
13054 string srclng = "";
13055 string dstlng = SettingDialog.TranslateLanguage;
13057 if (srclng != dstlng && _bing.Translate("", dstlng, str, out buf))
13059 PostBrowser.DocumentText = createDetailHtml(buf);
13063 if (msg.StartsWith("Err:"))
13064 StatusLabel.Text = msg;
13068 private void TranslationToolStripMenuItem_Click(object sender, EventArgs e)
13070 if (!this.ExistCurrentPost) return;
13071 doTranslation(_curPost.TextFromApi);
13074 private void SelectionTranslationToolStripMenuItem_Click(object sender, EventArgs e)
13076 doTranslation(WebBrowser_GetSelectionText(ref PostBrowser));
13079 private bool ExistCurrentPost
13083 if (_curPost == null) return false;
13084 if (_curPost.IsDeleted) return false;
13089 private void ShowUserTimelineToolStripMenuItem_Click(object sender, EventArgs e)
13091 ShowUserTimeline();
13094 public bool FavEventChangeUnread
13096 get { return SettingDialog.FavEventUnread; }
13099 private string GetUserIdFromCurPostOrInput(string caption)
13102 if (_curPost != null)
13104 id = _curPost.ScreenName;
13106 using (InputTabName inputName = new InputTabName())
13108 inputName.FormTitle = caption;
13109 inputName.FormDescription = Properties.Resources.FRMessage1;
13110 inputName.TabName = id;
13111 if (inputName.ShowDialog() == DialogResult.OK &&
13112 !string.IsNullOrEmpty(inputName.TabName.Trim()))
13114 id = inputName.TabName.Trim();
13124 private void UserTimelineToolStripMenuItem_Click(object sender, EventArgs e)
13126 string id = GetUserIdFromCurPostOrInput("Show UserTimeline");
13127 if (!string.IsNullOrEmpty(id))
13129 AddNewTabForUserTimeline(id);
13133 private void UserFavorareToolStripMenuItem_Click(object sender, EventArgs e)
13135 string id = GetUserIdFromCurPostOrInput("Show Favstar");
13136 if (!string.IsNullOrEmpty(id))
13138 OpenUriAsync(Properties.Resources.FavstarUrl + "users/" + id + "/recent");
13142 private void SystemEvents_PowerModeChanged(object sender, Microsoft.Win32.PowerModeChangedEventArgs e)
13144 if (e.Mode == Microsoft.Win32.PowerModes.Resume) osResumed = true;
13147 private void TimelineRefreshEnableChange(bool isEnable)
13151 tw.StartUserStream();
13155 tw.StopUserStream();
13157 TimerTimeline.Enabled = isEnable;
13160 private void StopRefreshAllMenuItem_CheckedChanged(object sender, EventArgs e)
13162 TimelineRefreshEnableChange(!StopRefreshAllMenuItem.Checked);
13165 private void OpenUserAppointUrl()
13167 if (SettingDialog.UserAppointUrl != null)
13169 if (SettingDialog.UserAppointUrl.Contains("{ID}") || SettingDialog.UserAppointUrl.Contains("{STATUS}"))
13171 if (_curPost != null)
13173 string xUrl = SettingDialog.UserAppointUrl;
13174 xUrl = xUrl.Replace("{ID}", _curPost.ScreenName);
13175 if (_curPost.RetweetedId != 0)
13177 xUrl = xUrl.Replace("{STATUS}", _curPost.RetweetedId.ToString());
13181 xUrl = xUrl.Replace("{STATUS}", _curPost.StatusId.ToString());
13183 OpenUriAsync(xUrl);
13188 OpenUriAsync(SettingDialog.UserAppointUrl);
13193 private void OpenUserSpecifiedUrlMenuItem_Click(object sender, EventArgs e)
13195 OpenUserAppointUrl();
13198 private void ImageSelectionPanel_VisibleChanged(object sender, EventArgs e)
13200 this.StatusText_TextChanged(null, null);
13203 private void SourceCopyMenuItem_Click(object sender, EventArgs e)
13205 string selText = SourceLinkLabel.Text;
13208 Clipboard.SetDataObject(selText, false, 5, 100);
13210 catch (Exception ex)
13212 MessageBox.Show(ex.Message);
13216 private void SourceUrlCopyMenuItem_Click(object sender, EventArgs e)
13218 string selText = (string)SourceLinkLabel.Tag;
13221 Clipboard.SetDataObject(selText, false, 5, 100);
13223 catch (Exception ex)
13225 MessageBox.Show(ex.Message);
13229 private void ContextMenuSource_Opening(object sender, CancelEventArgs e)
13231 if (_curPost == null || !ExistCurrentPost || _curPost.IsDm)
13233 SourceCopyMenuItem.Enabled = false;
13234 SourceUrlCopyMenuItem.Enabled = false;
13238 SourceCopyMenuItem.Enabled = true;
13239 SourceUrlCopyMenuItem.Enabled = true;
13243 private void GrowlHelper_Callback(object sender, GrowlHelper.NotifyCallbackEventArgs e)
13245 if (Form.ActiveForm == null)
13247 this.BeginInvoke((Action) (() =>
13249 this.Visible = true;
13250 if (this.WindowState == FormWindowState.Minimized) this.WindowState = FormWindowState.Normal;
13252 this.BringToFront();
13253 if (e.NotifyType == GrowlHelper.NotifyType.DirectMessage)
13255 if (!this.GoDirectMessage(e.StatusId)) this.StatusText.Focus();
13259 if (!this.GoStatus(e.StatusId)) this.StatusText.Focus();
13265 private void ReplaceAppName()
13267 MatomeMenuItem.Text = MyCommon.ReplaceAppName(MatomeMenuItem.Text);
13268 AboutMenuItem.Text = MyCommon.ReplaceAppName(AboutMenuItem.Text);
13271 private void tweetThumbnail1_ThumbnailLoading(object sender, EventArgs e)
13273 this.SplitContainer3.Panel2Collapsed = false;
13276 private void tweetThumbnail1_ThumbnailDoubleClick(object sender, ThumbnailDoubleClickEventArgs e)
13278 this.OpenThumbnailPicture(e.Thumbnail);
13281 private void tweetThumbnail1_ThumbnailImageSearchClick(object sender, ThumbnailImageSearchEventArgs e)
13283 this.OpenUriAsync(e.ImageUrl);
13286 private void OpenThumbnailPicture(ThumbnailInfo thumbnail)
13288 this.OpenUriAsync(Uri.EscapeUriString(thumbnail.ImageUrl));
13291 private void TwitterApiStatusToolStripMenuItem_Click(object sender, EventArgs e)
13293 this.OpenUriAsync(Twitter.ServiceAvailabilityStatusUrl);