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;
51 public partial class TweenMain : Form
54 private Size _mySize; //画面サイズ
55 private Point _myLoc; //画面位置
56 private int _mySpDis; //区切り位置
57 private int _mySpDis2; //発言欄区切り位置
58 private int _mySpDis3; //プレビュー区切り位置
59 private int _myAdSpDis; //Ad区切り位置
60 private int _iconSz; //アイコンサイズ(現在は16、24、48の3種類。将来直接数字指定可能とする 注:24x24の場合に26と指定しているのはMSゴシック系フォントのための仕様)
61 private bool _iconCol; //1列表示の時true(48サイズのとき)
64 private bool _initial; //true:起動時処理中
65 private bool _initialLayout = true;
66 private bool _ignoreConfigSave; //true:起動時処理中
67 private bool _tabDrag; //タブドラッグ中フラグ(DoDragDropを実行するかの判定用)
68 private TabPage _beforeSelectedTab; //タブが削除されたときに前回選択されていたときのタブを選択する為に保持
69 private Point _tabMouseDownPoint;
70 private string _rclickTabName; //右クリックしたタブの名前(Tabコントロール機能不足対応)
71 private readonly object _syncObject = new object(); //ロック用
72 private const string detailHtmlFormatMono1 = "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=8\"><style type=\"text/css\"><!-- pre {font-family: \"";
73 private const string detailHtmlFormat2 = "\", sans-serif; font-size: ";
74 private const string detailHtmlFormat3 = "pt; margin: 0; word-wrap: break-word; color:rgb(";
75 private const string detailHtmlFormat4 = ");} a:link, a:visited, a:active, a:hover {color:rgb(";
76 private const string detailHtmlFormat5 = "); } --></style></head><body style=\"margin:0px; background-color:rgb(";
77 private const string detailHtmlFormatMono6 = ");\"><pre>";
78 private const string detailHtmlFormatMono7 = "</pre></body></html>";
79 private const string detailHtmlFormat1 = "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=8\"><style type=\"text/css\"><!-- p {font-family: \"";
80 private const string detailHtmlFormat6 = ");\"><p><span style=\"vertical-align:text-bottom\">";
81 private const string detailHtmlFormat7 = "</span></p></body></html>";
82 private string detailHtmlFormatHeader;
83 private string detailHtmlFormatFooter;
84 private bool _myStatusError = false;
85 private bool _myStatusOnline = false;
86 private bool soundfileListup = false;
87 private SpaceKeyCanceler _spaceKeyCanceler;
88 private FormWindowState _formWindowState = FormWindowState.Normal; // フォームの状態保存用 通知領域からアイコンをクリックして復帰した際に使用する
91 //private SettingToConfig _cfg; //旧
92 private SettingLocal _cfgLocal;
93 private SettingCommon _cfgCommon;
94 private bool _modifySettingLocal = false;
95 private bool _modifySettingCommon = false;
96 private bool _modifySettingAtId = false;
99 private Twitter tw = new Twitter();
102 private GrowlHelper gh = new GrowlHelper(Application.ProductName);
105 private AppendSettingDialog SettingDialog = AppendSettingDialog.Instance; //設定画面インスタンス
106 private SearchWord SearchDialog = new SearchWord(); //検索画面インスタンス
107 private FilterDialog fltDialog = new FilterDialog(); //フィルター編集画面
108 private OpenURL UrlDialog = new OpenURL();
109 public AtIdSupplement AtIdSupl; //@id補助
110 public AtIdSupplement HashSupl; //Hashtag補助
111 public HashtagManage HashMgr;
112 private EventViewerDialog evtDialog;
115 private Font _fntUnread; //未読用フォント
116 private Color _clUnread; //未読用文字色
117 private Font _fntReaded; //既読用フォント
118 private Color _clReaded; //既読用文字色
119 private Color _clFav; //Fav用文字色
120 private Color _clOWL; //片思い用文字色
121 private Color _clRetweet; //Retweet用文字色
122 private Font _fntDetail; //発言詳細部用フォント
123 private Color _clDetail; //発言詳細部用色
124 private Color _clDetailLink; //発言詳細部用リンク文字色
125 private Color _clDetailBackcolor; //発言詳細部用背景色
126 private Color _clSelf; //自分の発言用背景色
127 private Color _clAtSelf; //自分宛返信用背景色
128 private Color _clTarget; //選択発言者の他の発言用背景色
129 private Color _clAtTarget; //選択発言中の返信先用背景色
130 private Color _clAtFromTarget; //選択発言者への返信発言用背景色
131 private Color _clAtTo; //選択発言の唯一@先
132 private Color _clListBackcolor; //リスト部通常発言背景色
133 private Color _clInputBackcolor; //入力欄背景色
134 private Color _clInputFont; //入力欄文字色
135 private Font _fntInputFont; //入力欄フォント
136 private IDictionary<string, Image> TIconDic; //アイコン画像リスト
137 private Icon NIconAt; //At.ico タスクトレイアイコン:通常時
138 private Icon NIconAtRed; //AtRed.ico タスクトレイアイコン:通信エラー時
139 private Icon NIconAtSmoke; //AtSmoke.ico タスクトレイアイコン:オフライン時
140 private Icon[] NIconRefresh = new Icon[4]; //Refresh.ico タスクトレイアイコン:更新中(アニメーション用に4種類を保持するリスト)
141 private Icon TabIcon; //Tab.ico 未読のあるタブ用アイコン
142 private Icon MainIcon; //Main.ico 画面左上のアイコン
143 private Icon ReplyIcon; //5g
144 private Icon ReplyIconBlink; //6g
146 private PostClass _anchorPost;
147 private bool _anchorFlag; //true:関連発言移動中(関連移動以外のオペレーションをするとfalseへ。trueだとリスト背景色をアンカー発言選択中として描画)
149 private List<PostingStatus> _history = new List<PostingStatus>(); //発言履歴
150 private int _hisIdx; //発言履歴カレントインデックス
152 //発言投稿時のAPI引数(発言編集時に設定。手書きreplyでは設定されない)
153 private long _reply_to_id; // リプライ先のステータスID 0の場合はリプライではない 注:複数あてのものはリプライではない
154 private string _reply_to_name; // リプライ先ステータスの書き込み者の名前
157 private List<DateTime> _postTimestamps = new List<DateTime>();
158 private List<DateTime> _favTimestamps = new List<DateTime>();
159 private Dictionary<DateTime, int> _tlTimestamps = new Dictionary<DateTime, int>();
160 private int _tlCount;
163 private SolidBrush _brsHighLight = new SolidBrush(Color.FromKnownColor(KnownColor.Highlight));
164 private SolidBrush _brsHighLightText = new SolidBrush(Color.FromKnownColor(KnownColor.HighlightText));
165 private SolidBrush _brsForeColorUnread;
166 private SolidBrush _brsForeColorReaded;
167 private SolidBrush _brsForeColorFav;
168 private SolidBrush _brsForeColorOWL;
169 private SolidBrush _brsForeColorRetweet;
170 private SolidBrush _brsBackColorMine;
171 private SolidBrush _brsBackColorAt;
172 private SolidBrush _brsBackColorYou;
173 private SolidBrush _brsBackColorAtYou;
174 private SolidBrush _brsBackColorAtFromTarget;
175 private SolidBrush _brsBackColorAtTo;
176 private SolidBrush _brsBackColorNone;
177 private SolidBrush _brsDeactiveSelection = new SolidBrush(Color.FromKnownColor(KnownColor.ButtonFace)); //Listにフォーカスないときの選択行の背景色
178 private StringFormat sfTab = new StringFormat();
180 //////////////////////////////////////////////////////////////////////////////////////////////////////////
181 private ToolStripAPIGauge _apiGauge = new ToolStripAPIGauge();
182 private TabInformations _statuses;
183 private ListViewItem[] _itemCache;
184 private int _itemCacheIndex;
185 private PostClass[] _postCache;
186 private TabPage _curTab;
187 private int _curItemIndex;
188 private DetailsListView _curList;
189 private PostClass _curPost;
190 private bool _isColumnChanged = false;
191 private bool _waitTimeline = false;
192 private bool _waitReply = false;
193 private bool _waitDm = false;
194 private bool _waitFav = false;
195 private bool _waitPubSearch = false;
196 private bool _waitUserTimeline = false;
197 private bool _waitLists = false;
198 private BackgroundWorker[] _bw = new BackgroundWorker[20];
199 private BackgroundWorker _bwFollower;
200 private InternetSecurityManager SecurityManager;
202 private int UnreadCounter = -1;
203 private int UnreadAtCounter = -1;
205 private string[] ColumnOrgText = new string[9];
206 private string[] ColumnText = new string[9];
208 private bool _DoFavRetweetFlags = false;
209 private bool osResumed = false;
210 private Dictionary<string, IMultimediaShareService> pictureService;
212 //////////////////////////////////////////////////////////////////////////////////////////////////////////
213 private string _postBrowserStatusText = "";
215 private bool _colorize = false;
217 private System.Timers.Timer TimerTimeline = new System.Timers.Timer();
219 private ImageListViewItem displayItem;
222 private struct urlUndo
224 public string Before;
228 private List<urlUndo> urlUndoBuffer = null;
230 private struct ReplyChain
232 public long OriginalId;
233 public long InReplyToId;
234 public TabPage OriginalTab;
236 public ReplyChain(long originalId, long inReplyToId, TabPage originalTab)
238 this.OriginalId = originalId;
239 this.InReplyToId = inReplyToId;
240 this.OriginalTab = originalTab;
244 private Stack<ReplyChain> replyChains; //[, ]でのリプライ移動の履歴
245 private Stack<Tuple<TabPage, PostClass>> selectPostChains = new Stack<Tuple<TabPage, PostClass>>(); //ポスト選択履歴
247 //Backgroundworkerの処理結果通知用引数構造体
248 private class GetWorkerResult
250 public string retMsg = ""; //処理結果詳細メッセージ。エラー時に値がセットされる
251 public int page; //取得対象ページ番号
252 public int endPage = 0; //取得終了ページ番号(継続可能ならインクリメントされて返る。pageと比較して継続判定)
253 public MyCommon.WORKERTYPE type; //処理種別
254 public Dictionary<string, Image> imgs = null; //新規取得したアイコンイメージ
255 public string tName = ""; //Fav追加・削除時のタブ名
256 public List<long> ids = null; //Fav追加・削除時のID
257 public List<long> sIds = null; //Fav追加・削除成功分のID
258 public bool newDM = false;
260 public PostingStatus status;
263 //Backgroundworkerへ処理内容を通知するための引数用構造体
264 private class GetWorkerArg
266 public int page; //処理対象ページ番号
267 public int endPage; //処理終了ページ番号(起動時の読み込みページ数。通常時はpageと同じ値をセット)
268 public MyCommon.WORKERTYPE type; //処理種別
269 public string url = ""; //URLをブラウザで開くときのアドレス
270 public PostingStatus status = new PostingStatus(); //発言POST時の発言内容
271 public List<long> ids; //Fav追加・削除時のItemIndex
272 public List<long> sIds; //Fav追加・削除成功分のItemIndex
273 public string tName = ""; //Fav追加・削除時のタブ名
277 private enum SEARCHTYPE
284 private class PostingStatus
286 public string status = "";
287 public long inReplyToId = 0;
288 public string inReplyToName = "";
289 public string imageService = ""; //画像投稿サービス名
290 public string imagePath = "";
291 public PostingStatus()
294 public PostingStatus(string status, long replyToId, string replyToName)
296 this.status = status;
297 this.inReplyToId = replyToId;
298 this.inReplyToName = replyToName;
302 private class SpaceKeyCanceler : NativeWindow, IDisposable
304 int WM_KEYDOWN = 0x100;
307 public SpaceKeyCanceler(Control control)
309 this.AssignHandle(control.Handle);
312 protected override void WndProc(ref Message m)
314 if ((m.Msg == WM_KEYDOWN) && ((int)m.WParam == VK_SPACE))
316 if (SpaceCancel != null)
317 SpaceCancel(this, EventArgs.Empty);
324 public event EventHandler SpaceCancel;
326 public void Dispose()
328 this.ReleaseHandle();
332 private void TweenMain_Activated(object sender, EventArgs e)
334 //画面がアクティブになったら、発言欄の背景色戻す
335 if (StatusText.Focused)
337 this.StatusText_Enter(this.StatusText, System.EventArgs.Empty);
341 private void TweenMain_Disposed(object sender, EventArgs e)
344 SettingDialog.Dispose();
345 SearchDialog.Dispose();
348 _spaceKeyCanceler.Dispose();
349 if (NIconAt != null) NIconAt.Dispose();
350 if (NIconAtRed != null) NIconAtRed.Dispose();
351 if (NIconAtSmoke != null) NIconAtSmoke.Dispose();
352 if (NIconRefresh[0] != null) NIconRefresh[0].Dispose();
353 if (NIconRefresh[1] != null) NIconRefresh[1].Dispose();
354 if (NIconRefresh[2] != null) NIconRefresh[2].Dispose();
355 if (NIconRefresh[3] != null) NIconRefresh[3].Dispose();
356 if (TabIcon != null) TabIcon.Dispose();
357 if (MainIcon != null) MainIcon.Dispose();
358 if (ReplyIcon != null) ReplyIcon.Dispose();
359 if (ReplyIconBlink != null) ReplyIconBlink.Dispose();
360 _brsHighLight.Dispose();
361 _brsHighLightText.Dispose();
362 if (_brsForeColorUnread != null) _brsForeColorUnread.Dispose();
363 if (_brsForeColorReaded != null) _brsForeColorReaded.Dispose();
364 if (_brsForeColorFav != null) _brsForeColorFav.Dispose();
365 if (_brsForeColorOWL != null) _brsForeColorOWL.Dispose();
366 if (_brsForeColorRetweet != null) _brsForeColorRetweet.Dispose();
367 if (_brsBackColorMine != null) _brsBackColorMine.Dispose();
368 if (_brsBackColorAt != null) _brsBackColorAt.Dispose();
369 if (_brsBackColorYou != null) _brsBackColorYou.Dispose();
370 if (_brsBackColorAtYou != null) _brsBackColorAtYou.Dispose();
371 if (_brsBackColorAtFromTarget != null) _brsBackColorAtFromTarget.Dispose();
372 if (_brsBackColorAtTo != null) _brsBackColorAtTo.Dispose();
373 if (_brsBackColorNone != null) _brsBackColorNone.Dispose();
374 if (_brsDeactiveSelection != null) _brsDeactiveSelection.Dispose();
377 foreach (BackgroundWorker bw in _bw)
382 if (_bwFollower != null)
384 _bwFollower.Dispose();
386 this._apiGauge.Dispose();
387 if (TIconDic != null)
389 ((ImageDictionary)this.TIconDic).PauseGetImage = true;
390 ((IDisposable)TIconDic).Dispose();
392 // 終了時にRemoveHandlerしておかないとメモリリークする
393 // http://msdn.microsoft.com/ja-jp/library/microsoft.win32.systemevents.powermodechanged.aspx
394 Microsoft.Win32.SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
397 private void LoadIcon(ref Icon IconInstance, string FileName)
399 string dir = Application.StartupPath;
400 if (File.Exists(Path.Combine(dir, FileName)))
404 IconInstance = new Icon(Path.Combine(dir, FileName));
412 private void LoadIcons()
416 string dir = Application.StartupPath;
418 NIconAt = Properties.Resources.At;
419 NIconAtRed = Properties.Resources.AtRed;
420 NIconAtSmoke = Properties.Resources.AtSmoke;
421 NIconRefresh[0] = Properties.Resources.Refresh;
422 NIconRefresh[1] = Properties.Resources.Refresh2;
423 NIconRefresh[2] = Properties.Resources.Refresh3;
424 NIconRefresh[3] = Properties.Resources.Refresh4;
425 TabIcon = Properties.Resources.TabIcon;
426 MainIcon = Properties.Resources.MIcon;
427 ReplyIcon = Properties.Resources.Reply;
428 ReplyIconBlink = Properties.Resources.ReplyBlink;
430 if (!Directory.Exists(Path.Combine(dir, "Icons")))
433 LoadIcon(ref NIconAt, "Icons\\At.ico");
436 LoadIcon(ref NIconAtRed, "Icons\\AtRed.ico");
439 LoadIcon(ref NIconAtSmoke, "Icons\\AtSmoke.ico");
442 //アニメーション対応により4種類読み込み
443 LoadIcon(ref NIconRefresh[0], "Icons\\Refresh.ico");
444 LoadIcon(ref NIconRefresh[1], "Icons\\Refresh2.ico");
445 LoadIcon(ref NIconRefresh[2], "Icons\\Refresh3.ico");
446 LoadIcon(ref NIconRefresh[3], "Icons\\Refresh4.ico");
449 LoadIcon(ref TabIcon, "Icons\\Tab.ico");
452 LoadIcon(ref MainIcon, "Icons\\MIcon.ico");
455 LoadIcon(ref ReplyIcon, "Icons\\Reply.ico");
458 LoadIcon(ref ReplyIconBlink, "Icons\\ReplyBlink.ico");
461 private void InitColumnText()
464 ColumnText[1] = Properties.Resources.AddNewTabText2;
465 ColumnText[2] = Properties.Resources.AddNewTabText3;
466 ColumnText[3] = Properties.Resources.AddNewTabText4_2;
467 ColumnText[4] = Properties.Resources.AddNewTabText5;
470 ColumnText[7] = "Source";
472 ColumnOrgText[0] = "";
473 ColumnOrgText[1] = Properties.Resources.AddNewTabText2;
474 ColumnOrgText[2] = Properties.Resources.AddNewTabText3;
475 ColumnOrgText[3] = Properties.Resources.AddNewTabText4_2;
476 ColumnOrgText[4] = Properties.Resources.AddNewTabText5;
477 ColumnOrgText[5] = "";
478 ColumnOrgText[6] = "";
479 ColumnOrgText[7] = "Source";
482 switch (_statuses.SortMode)
484 case IdComparerClass.ComparerMode.Nickname: //ニックネーム
487 case IdComparerClass.ComparerMode.Data: //本文
490 case IdComparerClass.ComparerMode.Id: //時刻=発言Id
493 case IdComparerClass.ComparerMode.Name: //名前
496 case IdComparerClass.ComparerMode.Source: //Source
503 if (_statuses.SortOrder == SortOrder.Descending)
505 // U+25BE BLACK DOWN-POINTING SMALL TRIANGLE
506 ColumnText[2] = ColumnOrgText[2] + "▾";
510 // U+25B4 BLACK UP-POINTING SMALL TRIANGLE
511 ColumnText[2] = ColumnOrgText[2] + "▴";
516 if (_statuses.SortOrder == SortOrder.Descending)
518 // U+25BE BLACK DOWN-POINTING SMALL TRIANGLE
519 ColumnText[c] = ColumnOrgText[c] + "▾";
523 // U+25B4 BLACK UP-POINTING SMALL TRIANGLE
524 ColumnText[c] = ColumnOrgText[c] + "▴";
529 private void InitializeTraceFrag()
532 TraceOutToolStripMenuItem.Checked = true;
533 MyCommon.TraceFlag = true;
535 if (!MyCommon.fileVersion.EndsWith("0"))
537 TraceOutToolStripMenuItem.Checked = true;
538 MyCommon.TraceFlag = true;
542 private void Form1_Load(object sender, EventArgs e)
544 _ignoreConfigSave = true;
545 this.Visible = false;
547 //Win32Api.SetProxy(HttpConnection.ProxyType.Specified, "127.0.0.1", 8080, "user", "pass")
549 SecurityManager = new InternetSecurityManager(PostBrowser);
551 MyCommon.TwitterApiInfo.Changed += SetStatusLabelApiHandler;
552 Microsoft.Win32.SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
554 string[] cmdArgs = Environment.GetCommandLineArgs();
555 if (cmdArgs.Length != 0 && cmdArgs.Contains("/d")) MyCommon.TraceFlag = true;
557 this._spaceKeyCanceler = new SpaceKeyCanceler(this.PostButton);
558 this._spaceKeyCanceler.SpaceCancel += spaceKeyCanceler_SpaceCancel;
560 Regex.CacheSize = 100;
562 MyCommon.fileVersion = ((AssemblyFileVersionAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyFileVersionAttribute), false)[0]).Version;
563 InitializeTraceFrag();
564 LoadIcons(); // アイコン読み込み
566 ThumbnailGenerator.InitializeGenerator();
569 _statuses = TabInformations.GetInstance();
572 this.Icon = MainIcon; //メインフォーム(TweenMain)
573 NotifyIcon1.Icon = NIconAt; //タスクトレイ
574 TabImage.Images.Add(TabIcon); //タブ見出し
576 SettingDialog.Owner = this;;
577 SearchDialog.Owner = this;
578 fltDialog.Owner = this;
579 UrlDialog.Owner = this;
581 _history.Add(new PostingStatus());
586 //<<<<<<<<<設定関連>>>>>>>>>
594 NewPostPopMenuItem.Checked = _cfgCommon.NewAllPop;
595 this.NotifyFileMenuItem.Checked = NewPostPopMenuItem.Checked;
598 _fntUnread = _cfgLocal.FontUnread;
599 _clUnread = _cfgLocal.ColorUnread;
600 _fntReaded = _cfgLocal.FontRead;
601 _clReaded = _cfgLocal.ColorRead;
602 _clFav = _cfgLocal.ColorFav;
603 _clOWL = _cfgLocal.ColorOWL;
604 _clRetweet = _cfgLocal.ColorRetweet;
605 _fntDetail = _cfgLocal.FontDetail;
606 _clDetail = _cfgLocal.ColorDetail;
607 _clDetailLink = _cfgLocal.ColorDetailLink;
608 _clDetailBackcolor = _cfgLocal.ColorDetailBackcolor;
609 _clSelf = _cfgLocal.ColorSelf;
610 _clAtSelf = _cfgLocal.ColorAtSelf;
611 _clTarget = _cfgLocal.ColorTarget;
612 _clAtTarget = _cfgLocal.ColorAtTarget;
613 _clAtFromTarget = _cfgLocal.ColorAtFromTarget;
614 _clAtTo = _cfgLocal.ColorAtTo;
615 _clListBackcolor = _cfgLocal.ColorListBackcolor;
616 _clInputBackcolor = _cfgLocal.ColorInputBackcolor;
617 _clInputFont = _cfgLocal.ColorInputFont;
618 _fntInputFont = _cfgLocal.FontInputFont;
620 _brsForeColorUnread = new SolidBrush(_clUnread);
621 _brsForeColorReaded = new SolidBrush(_clReaded);
622 _brsForeColorFav = new SolidBrush(_clFav);
623 _brsForeColorOWL = new SolidBrush(_clOWL);
624 _brsForeColorRetweet = new SolidBrush(_clRetweet);
625 _brsBackColorMine = new SolidBrush(_clSelf);
626 _brsBackColorAt = new SolidBrush(_clAtSelf);
627 _brsBackColorYou = new SolidBrush(_clTarget);
628 _brsBackColorAtYou = new SolidBrush(_clAtTarget);
629 _brsBackColorAtFromTarget = new SolidBrush(_clAtFromTarget);
630 _brsBackColorAtTo = new SolidBrush(_clAtTo);
631 //_brsBackColorNone = new SolidBrush(Color.FromKnownColor(KnownColor.Window));
632 _brsBackColorNone = new SolidBrush(_clListBackcolor);
634 // StringFormatオブジェクトへの事前設定
635 //sf.Alignment = StringAlignment.Near; // Textを近くへ配置(左から右の場合は左寄せ)
636 //sf.LineAlignment = StringAlignment.Near; // Textを近くへ配置(上寄せ)
637 //sf.FormatFlags = StringFormatFlags.LineLimit; //
638 sfTab.Alignment = StringAlignment.Center;
639 sfTab.LineAlignment = StringAlignment.Center;
642 HttpTwitter.TwitterUrl = _cfgCommon.TwitterUrl;
643 HttpTwitter.TwitterSearchUrl = _cfgCommon.TwitterSearchUrl;
644 SettingDialog.TwitterApiUrl = _cfgCommon.TwitterUrl;
645 SettingDialog.TwitterSearchApiUrl = _cfgCommon.TwitterSearchUrl;
648 if (string.IsNullOrEmpty(_cfgCommon.Token)) _cfgCommon.UserName = "";
649 tw.Initialize(_cfgCommon.Token, _cfgCommon.TokenSecret, _cfgCommon.UserName, _cfgCommon.UserId);
651 SettingDialog.UserAccounts = _cfgCommon.UserAccounts;
653 SettingDialog.TimelinePeriodInt = _cfgCommon.TimelinePeriod;
654 SettingDialog.ReplyPeriodInt = _cfgCommon.ReplyPeriod;
655 SettingDialog.DMPeriodInt = _cfgCommon.DMPeriod;
656 SettingDialog.PubSearchPeriodInt = _cfgCommon.PubSearchPeriod;
657 SettingDialog.UserTimelinePeriodInt = _cfgCommon.UserTimelinePeriod;
658 SettingDialog.ListsPeriodInt = _cfgCommon.ListsPeriod;
660 if (!cmdArgs.Contains("nolimit"))
662 if (SettingDialog.TimelinePeriodInt < 15 && SettingDialog.TimelinePeriodInt > 0) SettingDialog.TimelinePeriodInt = 15;
663 if (SettingDialog.ReplyPeriodInt < 15 && SettingDialog.ReplyPeriodInt > 0) SettingDialog.ReplyPeriodInt = 15;
664 if (SettingDialog.DMPeriodInt < 15 && SettingDialog.DMPeriodInt > 0) SettingDialog.DMPeriodInt = 15;
665 if (SettingDialog.PubSearchPeriodInt < 30 && SettingDialog.PubSearchPeriodInt > 0) SettingDialog.PubSearchPeriodInt = 30;
666 if (SettingDialog.UserTimelinePeriodInt < 15 && SettingDialog.UserTimelinePeriodInt > 0) SettingDialog.UserTimelinePeriodInt = 15;
667 if (SettingDialog.ListsPeriodInt < 15 && SettingDialog.ListsPeriodInt > 0) SettingDialog.ListsPeriodInt = 15;
670 //起動時読み込み分を既読にするか。trueなら既読として処理
671 SettingDialog.Readed = _cfgCommon.Read;
672 //新着取得時のリストスクロールをするか。trueならスクロールしない
673 ListLockMenuItem.Checked = _cfgCommon.ListLock;
674 this.LockListFileMenuItem.Checked = _cfgCommon.ListLock;
675 SettingDialog.IconSz = _cfgCommon.IconSize;
677 SettingDialog.Status = _cfgLocal.StatusText;
679 SettingDialog.UnreadManage = _cfgCommon.UnreadManage;
681 SettingDialog.PlaySound = _cfgCommon.PlaySound;
682 PlaySoundMenuItem.Checked = SettingDialog.PlaySound;
683 this.PlaySoundFileMenuItem.Checked = SettingDialog.PlaySound;
684 //片思い表示。trueなら片思い表示する
685 SettingDialog.OneWayLove = _cfgCommon.OneWayLove;
687 SettingDialog.FontUnread = _fntUnread;
688 SettingDialog.ColorUnread = _clUnread;
689 SettingDialog.FontReaded = _fntReaded;
690 SettingDialog.ColorReaded = _clReaded;
691 SettingDialog.ColorFav = _clFav;
692 SettingDialog.ColorOWL = _clOWL;
693 SettingDialog.ColorRetweet = _clRetweet;
694 SettingDialog.FontDetail = _fntDetail;
695 SettingDialog.ColorDetail = _clDetail;
696 SettingDialog.ColorDetailLink = _clDetailLink;
697 SettingDialog.ColorDetailBackcolor = _clDetailBackcolor;
698 SettingDialog.ColorSelf = _clSelf;
699 SettingDialog.ColorAtSelf = _clAtSelf;
700 SettingDialog.ColorTarget = _clTarget;
701 SettingDialog.ColorAtTarget = _clAtTarget;
702 SettingDialog.ColorAtFromTarget = _clAtFromTarget;
703 SettingDialog.ColorAtTo = _clAtTo;
704 SettingDialog.ColorListBackcolor = _clListBackcolor;
705 SettingDialog.ColorInputBackcolor = _clInputBackcolor;
706 SettingDialog.ColorInputFont = _clInputFont;
707 SettingDialog.FontInputFont = _fntInputFont;
709 SettingDialog.NameBalloon = _cfgCommon.NameBalloon;
710 SettingDialog.PostCtrlEnter = _cfgCommon.PostCtrlEnter;
711 SettingDialog.PostShiftEnter = _cfgCommon.PostShiftEnter;
713 SettingDialog.CountApi = _cfgCommon.CountApi;
714 SettingDialog.CountApiReply = _cfgCommon.CountApiReply;
715 if (SettingDialog.CountApi < 20 || SettingDialog.CountApi > 200) SettingDialog.CountApi = 60;
716 if (SettingDialog.CountApiReply < 20 || SettingDialog.CountApiReply > 200) SettingDialog.CountApiReply = 40;
718 SettingDialog.BrowserPath = _cfgLocal.BrowserPath;
719 SettingDialog.PostAndGet = _cfgCommon.PostAndGet;
720 SettingDialog.UseRecommendStatus = _cfgLocal.UseRecommendStatus;
721 SettingDialog.DispUsername = _cfgCommon.DispUsername;
722 SettingDialog.CloseToExit = _cfgCommon.CloseToExit;
723 SettingDialog.MinimizeToTray = _cfgCommon.MinimizeToTray;
724 SettingDialog.DispLatestPost = _cfgCommon.DispLatestPost;
725 SettingDialog.SortOrderLock = _cfgCommon.SortOrderLock;
726 SettingDialog.TinyUrlResolve = _cfgCommon.TinyUrlResolve;
727 SettingDialog.ShortUrlForceResolve = _cfgCommon.ShortUrlForceResolve;
729 SettingDialog.SelectedProxyType = _cfgLocal.ProxyType;
730 SettingDialog.ProxyAddress = _cfgLocal.ProxyAddress;
731 SettingDialog.ProxyPort = _cfgLocal.ProxyPort;
732 SettingDialog.ProxyUser = _cfgLocal.ProxyUser;
733 SettingDialog.ProxyPassword = _cfgLocal.ProxyPassword;
735 SettingDialog.PeriodAdjust = _cfgCommon.PeriodAdjust;
736 SettingDialog.StartupVersion = _cfgCommon.StartupVersion;
737 SettingDialog.StartupFollowers = _cfgCommon.StartupFollowers;
738 SettingDialog.RestrictFavCheck = _cfgCommon.RestrictFavCheck;
739 SettingDialog.AlwaysTop = _cfgCommon.AlwaysTop;
740 SettingDialog.UrlConvertAuto = false;
741 //SettingDialog.UrlConvertAuto = _cfgCommon.UrlConvertAuto;
743 SettingDialog.OutputzEnabled = _cfgCommon.Outputz;
744 SettingDialog.OutputzKey = _cfgCommon.OutputzKey;
745 SettingDialog.OutputzUrlmode = _cfgCommon.OutputzUrlMode;
747 SettingDialog.UseUnreadStyle = _cfgCommon.UseUnreadStyle;
748 SettingDialog.DefaultTimeOut = _cfgCommon.DefaultTimeOut;
749 SettingDialog.RetweetNoConfirm = _cfgCommon.RetweetNoConfirm;
750 SettingDialog.PlaySound = _cfgCommon.PlaySound;
751 SettingDialog.DateTimeFormat = _cfgCommon.DateTimeFormat;
752 SettingDialog.LimitBalloon = _cfgCommon.LimitBalloon;
753 SettingDialog.EventNotifyEnabled = _cfgCommon.EventNotifyEnabled;
754 SettingDialog.EventNotifyFlag = _cfgCommon.EventNotifyFlag;
755 SettingDialog.IsMyEventNotifyFlag = _cfgCommon.IsMyEventNotifyFlag;
756 SettingDialog.ForceEventNotify = _cfgCommon.ForceEventNotify;
757 SettingDialog.FavEventUnread = _cfgCommon.FavEventUnread;
758 SettingDialog.TranslateLanguage = _cfgCommon.TranslateLanguage;
759 SettingDialog.EventSoundFile = _cfgCommon.EventSoundFile;
761 //廃止サービスが選択されていた場合bit.lyへ読み替え
762 if (_cfgCommon.AutoShortUrlFirst < 0)
763 _cfgCommon.AutoShortUrlFirst = MyCommon.UrlConverter.Uxnu;
765 SettingDialog.AutoShortUrlFirst = _cfgCommon.AutoShortUrlFirst;
766 SettingDialog.TabIconDisp = _cfgCommon.TabIconDisp;
767 SettingDialog.ReplyIconState = _cfgCommon.ReplyIconState;
768 SettingDialog.ReadOwnPost = _cfgCommon.ReadOwnPost;
769 SettingDialog.GetFav = _cfgCommon.GetFav;
770 SettingDialog.ReadOldPosts = _cfgCommon.ReadOldPosts;
771 SettingDialog.UseSsl = _cfgCommon.UseSsl;
772 SettingDialog.BitlyUser = _cfgCommon.BilyUser;
773 SettingDialog.BitlyPwd = _cfgCommon.BitlyPwd;
774 SettingDialog.ShowGrid = _cfgCommon.ShowGrid;
775 SettingDialog.Language = _cfgCommon.Language;
776 SettingDialog.UseAtIdSupplement = _cfgCommon.UseAtIdSupplement;
777 SettingDialog.UseHashSupplement = _cfgCommon.UseHashSupplement;
778 SettingDialog.PreviewEnable = _cfgCommon.PreviewEnable;
779 AtIdSupl = new AtIdSupplement(SettingAtIdList.Load().AtIdList, "@");
781 SettingDialog.IsMonospace = _cfgCommon.IsMonospace;
782 if (SettingDialog.IsMonospace)
784 detailHtmlFormatHeader = detailHtmlFormatMono1;
785 detailHtmlFormatFooter = detailHtmlFormatMono7;
789 detailHtmlFormatHeader = detailHtmlFormat1;
790 detailHtmlFormatFooter = detailHtmlFormat7;
792 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();
793 if (SettingDialog.IsMonospace)
795 detailHtmlFormatHeader += detailHtmlFormatMono6;
799 detailHtmlFormatHeader += detailHtmlFormat6;
801 this.IdeographicSpaceToSpaceToolStripMenuItem.Checked = _cfgCommon.WideSpaceConvert;
802 this.ToolStripFocusLockMenuItem.Checked = _cfgCommon.FocusLockToStatusText;
804 //Regex statregex = new Regex("^0*");
805 SettingDialog.RecommendStatusText = " [TWNv" + Regex.Replace(MyCommon.fileVersion.Replace(".", ""), "^0*", "") + "]";
810 if (DateTime.Now.ToString(SettingDialog.DateTimeFormat).Length == 0)
812 // このブロックは絶対に実行されないはず
813 // 変換が成功した場合にLengthが0にならない
814 SettingDialog.DateTimeFormat = "yyyy/MM/dd H:mm:ss";
817 catch (FormatException)
819 // FormatExceptionが発生したら初期値を設定 (=yyyy/MM/dd H:mm:ssとみなされる)
820 SettingDialog.DateTimeFormat = "yyyy/MM/dd H:mm:ss";
823 SettingDialog.Nicoms = _cfgCommon.Nicoms;
824 SettingDialog.HotkeyEnabled = _cfgCommon.HotkeyEnabled;
825 SettingDialog.HotkeyMod = _cfgCommon.HotkeyModifier;
826 SettingDialog.HotkeyKey = _cfgCommon.HotkeyKey;
827 SettingDialog.HotkeyValue = _cfgCommon.HotkeyValue;
829 SettingDialog.BlinkNewMentions = _cfgCommon.BlinkNewMentions;
831 SettingDialog.UseAdditionalCount = _cfgCommon.UseAdditionalCount;
832 SettingDialog.MoreCountApi = _cfgCommon.MoreCountApi;
833 SettingDialog.FirstCountApi = _cfgCommon.FirstCountApi;
834 SettingDialog.SearchCountApi = _cfgCommon.SearchCountApi;
835 SettingDialog.FavoritesCountApi = _cfgCommon.FavoritesCountApi;
836 SettingDialog.UserTimelineCountApi = _cfgCommon.UserTimelineCountApi;
837 SettingDialog.ListCountApi = _cfgCommon.ListCountApi;
839 SettingDialog.UserstreamStartup = _cfgCommon.UserstreamStartup;
840 SettingDialog.UserstreamPeriodInt = _cfgCommon.UserstreamPeriod;
841 SettingDialog.OpenUserTimeline = _cfgCommon.OpenUserTimeline;
842 SettingDialog.ListDoubleClickAction = _cfgCommon.ListDoubleClickAction;
843 SettingDialog.UserAppointUrl = _cfgCommon.UserAppointUrl;
844 SettingDialog.HideDuplicatedRetweets = _cfgCommon.HideDuplicatedRetweets;
846 SettingDialog.IsPreviewFoursquare = _cfgCommon.IsPreviewFoursquare;
847 SettingDialog.MapThumbnailProvider = _cfgCommon.MapThumbnailProvider;
848 SettingDialog.MapThumbnailHeight = _cfgCommon.MapThumbnailHeight;
849 SettingDialog.MapThumbnailWidth = _cfgCommon.MapThumbnailWidth;
850 SettingDialog.MapThumbnailZoom = _cfgCommon.MapThumbnailZoom;
851 SettingDialog.IsListStatusesIncludeRts = _cfgCommon.IsListsIncludeRts;
852 SettingDialog.TabMouseLock = _cfgCommon.TabMouseLock;
853 SettingDialog.IsRemoveSameEvent = _cfgCommon.IsRemoveSameEvent;
854 SettingDialog.IsNotifyUseGrowl = _cfgCommon.IsUseNotifyGrowl;
857 HashSupl = new AtIdSupplement(_cfgCommon.HashTags, "#");
858 HashMgr = new HashtagManage(HashSupl,
859 _cfgCommon.HashTags.ToArray(),
860 _cfgCommon.HashSelected,
861 _cfgCommon.HashIsPermanent,
862 _cfgCommon.HashIsHead,
863 _cfgCommon.HashIsNotAddToAtReply);
864 if (!string.IsNullOrEmpty(HashMgr.UseHash) && HashMgr.IsPermanent) HashStripSplitButton.Text = HashMgr.UseHash;
871 TIconDic = new ImageDictionary(5);
875 MessageBox.Show("Please install [.NET Framework 4 (Full)].");
879 ((ImageDictionary)this.TIconDic).PauseGetImage = false;
881 bool saveRequired = false;
882 bool firstRun = false;
884 //ユーザー名、パスワードが未設定なら設定画面を表示(初回起動時など)
885 if (string.IsNullOrEmpty(tw.Username))
889 SettingDialog.ShowInTaskbar = true;
891 //設定せずにキャンセルされた場合はプログラム終了
892 if (SettingDialog.ShowDialog(this) == DialogResult.Cancel)
894 Application.Exit(); //強制終了
897 //設定されたが、依然ユーザー名とパスワードが未設定ならプログラム終了
898 if (string.IsNullOrEmpty(tw.Username))
900 Application.Exit(); //強制終了
903 SettingDialog.ShowInTaskbar = false;
906 _fntUnread = SettingDialog.FontUnread;
907 _clUnread = SettingDialog.ColorUnread;
908 _fntReaded = SettingDialog.FontReaded;
909 _clReaded = SettingDialog.ColorReaded;
910 _clFav = SettingDialog.ColorFav;
911 _clOWL = SettingDialog.ColorOWL;
912 _clRetweet = SettingDialog.ColorRetweet;
913 _fntDetail = SettingDialog.FontDetail;
914 _clDetail = SettingDialog.ColorDetail;
915 _clDetailLink = SettingDialog.ColorDetailLink;
916 _clDetailBackcolor = SettingDialog.ColorDetailBackcolor;
917 _clSelf = SettingDialog.ColorSelf;
918 _clAtSelf = SettingDialog.ColorAtSelf;
919 _clTarget = SettingDialog.ColorTarget;
920 _clAtTarget = SettingDialog.ColorAtTarget;
921 _clAtFromTarget = SettingDialog.ColorAtFromTarget;
922 _clAtTo = SettingDialog.ColorAtTo;
923 _clListBackcolor = SettingDialog.ColorListBackcolor;
924 _clInputBackcolor = SettingDialog.ColorInputBackcolor;
925 _clInputFont = SettingDialog.ColorInputFont;
926 _fntInputFont = SettingDialog.FontInputFont;
927 _brsForeColorUnread.Dispose();
928 _brsForeColorReaded.Dispose();
929 _brsForeColorFav.Dispose();
930 _brsForeColorOWL.Dispose();
931 _brsForeColorRetweet.Dispose();
932 _brsForeColorUnread = new SolidBrush(_clUnread);
933 _brsForeColorReaded = new SolidBrush(_clReaded);
934 _brsForeColorFav = new SolidBrush(_clFav);
935 _brsForeColorOWL = new SolidBrush(_clOWL);
936 _brsForeColorRetweet = new SolidBrush(_clRetweet);
937 _brsBackColorMine.Dispose();
938 _brsBackColorAt.Dispose();
939 _brsBackColorYou.Dispose();
940 _brsBackColorAtYou.Dispose();
941 _brsBackColorAtFromTarget.Dispose();
942 _brsBackColorAtTo.Dispose();
943 _brsBackColorNone.Dispose();
944 _brsBackColorMine = new SolidBrush(_clSelf);
945 _brsBackColorAt = new SolidBrush(_clAtSelf);
946 _brsBackColorYou = new SolidBrush(_clTarget);
947 _brsBackColorAtYou = new SolidBrush(_clAtTarget);
948 _brsBackColorAtFromTarget = new SolidBrush(_clAtFromTarget);
949 _brsBackColorAtTo = new SolidBrush(_clAtTo);
950 _brsBackColorNone = new SolidBrush(_clListBackcolor);
952 if (SettingDialog.IsMonospace)
954 detailHtmlFormatHeader = detailHtmlFormatMono1;
955 detailHtmlFormatFooter = detailHtmlFormatMono7;
959 detailHtmlFormatHeader = detailHtmlFormat1;
960 detailHtmlFormatFooter = detailHtmlFormat7;
962 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();
963 if (SettingDialog.IsMonospace)
965 detailHtmlFormatHeader += detailHtmlFormatMono6;
969 detailHtmlFormatHeader += detailHtmlFormat6;
971 //他の設定項目は、随時設定画面で保持している値を読み出して使用
974 if (SettingDialog.HotkeyEnabled)
977 HookGlobalHotkey.ModKeys modKey = HookGlobalHotkey.ModKeys.None;
978 if ((SettingDialog.HotkeyMod & Keys.Alt) == Keys.Alt) modKey = modKey | HookGlobalHotkey.ModKeys.Alt;
979 if ((SettingDialog.HotkeyMod & Keys.Control) == Keys.Control) modKey = modKey | HookGlobalHotkey.ModKeys.Ctrl;
980 if ((SettingDialog.HotkeyMod & Keys.Shift) == Keys.Shift) modKey = modKey | HookGlobalHotkey.ModKeys.Shift;
981 if ((SettingDialog.HotkeyMod & Keys.LWin) == Keys.LWin) modKey = modKey | HookGlobalHotkey.ModKeys.Win;
983 _hookGlobalHotkey.RegisterOriginalHotkey(SettingDialog.HotkeyKey, SettingDialog.HotkeyValue, modKey);
987 HttpConnection.InitializeConnection(SettingDialog.DefaultTimeOut,
988 SettingDialog.SelectedProxyType,
989 SettingDialog.ProxyAddress,
990 SettingDialog.ProxyPort,
991 SettingDialog.ProxyUser,
992 SettingDialog.ProxyPassword);
994 tw.RestrictFavCheck = SettingDialog.RestrictFavCheck;
995 tw.ReadOwnPost = SettingDialog.ReadOwnPost;
996 tw.UseSsl = SettingDialog.UseSsl;
997 ShortUrl.IsResolve = SettingDialog.TinyUrlResolve;
998 ShortUrl.IsForceResolve = SettingDialog.ShortUrlForceResolve;
999 ShortUrl.BitlyId = SettingDialog.BitlyUser;
1000 ShortUrl.BitlyKey = SettingDialog.BitlyPwd;
1001 HttpTwitter.TwitterUrl = _cfgCommon.TwitterUrl;
1002 HttpTwitter.TwitterSearchUrl = _cfgCommon.TwitterSearchUrl;
1003 tw.TrackWord = _cfgCommon.TrackWord;
1004 TrackToolStripMenuItem.Checked = !String.IsNullOrEmpty(tw.TrackWord);
1005 tw.AllAtReply = _cfgCommon.AllAtReply;
1006 AllrepliesToolStripMenuItem.Checked = tw.AllAtReply;
1008 Outputz.Key = SettingDialog.OutputzKey;
1009 Outputz.Enabled = SettingDialog.OutputzEnabled;
1010 switch (SettingDialog.OutputzUrlmode)
1012 case MyCommon.OutputzUrlmode.twittercom:
1013 Outputz.OutUrl = "http://twitter.com/";
1015 case MyCommon.OutputzUrlmode.twittercomWithUsername:
1016 Outputz.OutUrl = "http://twitter.com/" + tw.Username;
1021 this.CreatePictureServices();
1022 SetImageServiceCombo();
1023 ImageSelectionPanel.Enabled = false;
1025 ImageServiceCombo.SelectedIndex = _cfgCommon.UseImageService;
1028 this.ClientSize = _cfgLocal.FormSize;
1029 _mySize = _cfgLocal.FormSize; //サイズ保持(最小化・最大化されたまま終了した場合の対応用)
1030 _myLoc = _cfgLocal.FormLocation;
1032 if (this.WindowState != FormWindowState.Minimized)
1034 this.DesktopLocation = _cfgLocal.FormLocation;
1035 Rectangle tbarRect = new Rectangle(this.Location, new Size(_mySize.Width, SystemInformation.CaptionHeight));
1036 bool outOfScreen = true;
1037 if (Screen.AllScreens.Length == 1) //ハングするとの報告
1039 foreach (Screen scr in Screen.AllScreens)
1041 if (!Rectangle.Intersect(tbarRect, scr.Bounds).IsEmpty)
1043 outOfScreen = false;
1049 this.DesktopLocation = new Point(0, 0);
1050 _myLoc = this.DesktopLocation;
1054 this.TopMost = SettingDialog.AlwaysTop;
1055 _mySpDis = _cfgLocal.SplitterDistance;
1056 _mySpDis2 = _cfgLocal.StatusTextHeight;
1057 _mySpDis3 = _cfgLocal.PreviewDistance;
1058 if (_mySpDis3 == -1)
1060 _mySpDis3 = _mySize.Width - 150;
1061 if (_mySpDis3 < 1) _mySpDis3 = 50;
1062 _cfgLocal.PreviewDistance = _mySpDis3;
1064 _myAdSpDis = _cfgLocal.AdSplitterDistance;
1065 MultiLineMenuItem.Checked = _cfgLocal.StatusMultiline;
1066 //this.Tween_ClientSizeChanged(this, null);
1067 PlaySoundMenuItem.Checked = SettingDialog.PlaySound;
1068 this.PlaySoundFileMenuItem.Checked = SettingDialog.PlaySound;
1070 StatusText.Font = _fntInputFont;
1071 StatusText.ForeColor = _clInputFont;
1073 //全新着通知のチェック状態により、Reply&DMの新着通知有効無効切り替え(タブ別設定にするため削除予定)
1074 if (SettingDialog.UnreadManage == false)
1076 ReadedStripMenuItem.Enabled = false;
1077 UnreadStripMenuItem.Enabled = false;
1080 if (SettingDialog.IsNotifyUseGrowl) gh.RegisterGrowl();
1083 TimerTimeline.AutoReset = true;
1084 TimerTimeline.SynchronizingObject = this;
1086 TimerTimeline.Interval = 1000;
1087 TimerTimeline.Enabled = true;
1090 TimerRefreshIcon.Interval = 200;
1091 TimerRefreshIcon.Enabled = true;
1094 StatusLabel.Text = "";
1095 StatusLabel.AutoToolTip = false;
1096 StatusLabel.ToolTipText = "";
1098 lblLen.Text = GetRestStatusCount(true, false).ToString();
1100 ////////////////////////////////////////////////////////////////////////////////
1101 _statuses.SortOrder = (SortOrder)_cfgCommon.SortOrder;
1102 IdComparerClass.ComparerMode mode = IdComparerClass.ComparerMode.Id;
1103 switch (_cfgCommon.SortColumn)
1105 case 0: //0:アイコン,5:未読マーク,6:プロテクト・フィルターマーク
1109 mode = IdComparerClass.ComparerMode.Id; //Idソートに読み替え
1112 mode = IdComparerClass.ComparerMode.Nickname;
1115 mode = IdComparerClass.ComparerMode.Data;
1118 mode = IdComparerClass.ComparerMode.Id;
1121 mode = IdComparerClass.ComparerMode.Name;
1124 mode = IdComparerClass.ComparerMode.Source;
1127 _statuses.SortMode = mode;
1128 ////////////////////////////////////////////////////////////////////////////////
1130 switch (SettingDialog.IconSz)
1132 case MyCommon.IconSizes.IconNone:
1135 case MyCommon.IconSizes.Icon16:
1138 case MyCommon.IconSizes.Icon24:
1141 case MyCommon.IconSizes.Icon48:
1144 case MyCommon.IconSizes.Icon48_2:
1156 tw.IconSize = _iconSz;
1158 tw.TinyUrlResolve = SettingDialog.TinyUrlResolve;
1159 ShortUrl.IsForceResolve = SettingDialog.ShortUrlForceResolve;
1161 //発言詳細部アイコンをリストアイコンにサイズ変更
1168 tw.DetailIcon = TIconDic;
1170 StatusLabel.Text = Properties.Resources.Form1_LoadText1; //画面右下の状態表示を変更
1171 StatusLabelUrl.Text = ""; //画面左下のリンク先URL表示部を初期化
1172 NameLabel.Text = ""; //発言詳細部名前ラベル初期化
1173 DateTimeLabel.Text = ""; //発言詳細部日時ラベル初期化
1174 SourceLinkLabel.Text = ""; //Source部分初期化
1176 //<<<<<<<<タブ関連>>>>>>>
1177 //デフォルトタブの存在チェック、ない場合には追加
1178 if (_statuses.GetTabByType(MyCommon.TabUsageType.Home) == null)
1180 if (!_statuses.Tabs.ContainsKey(MyCommon.DEFAULTTAB.RECENT))
1182 _statuses.AddTab(MyCommon.DEFAULTTAB.RECENT, MyCommon.TabUsageType.Home, null);
1186 _statuses.Tabs[MyCommon.DEFAULTTAB.RECENT].TabType = MyCommon.TabUsageType.Home;
1189 if (_statuses.GetTabByType(MyCommon.TabUsageType.Mentions) == null)
1191 if (!_statuses.Tabs.ContainsKey(MyCommon.DEFAULTTAB.REPLY))
1193 _statuses.AddTab(MyCommon.DEFAULTTAB.REPLY, MyCommon.TabUsageType.Mentions, null);
1197 _statuses.Tabs[MyCommon.DEFAULTTAB.REPLY].TabType = MyCommon.TabUsageType.Mentions;
1200 if (_statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage) == null)
1202 if (!_statuses.Tabs.ContainsKey(MyCommon.DEFAULTTAB.DM))
1204 _statuses.AddTab(MyCommon.DEFAULTTAB.DM, MyCommon.TabUsageType.DirectMessage, null);
1208 _statuses.Tabs[MyCommon.DEFAULTTAB.DM].TabType = MyCommon.TabUsageType.DirectMessage;
1211 if (_statuses.GetTabByType(MyCommon.TabUsageType.Favorites) == null)
1213 if (!_statuses.Tabs.ContainsKey(MyCommon.DEFAULTTAB.FAV))
1215 _statuses.AddTab(MyCommon.DEFAULTTAB.FAV, MyCommon.TabUsageType.Favorites, null);
1219 _statuses.Tabs[MyCommon.DEFAULTTAB.FAV].TabType = MyCommon.TabUsageType.Favorites;
1222 foreach (string tn in _statuses.Tabs.Keys)
1224 if (_statuses.Tabs[tn].TabType == MyCommon.TabUsageType.Undefined)
1226 _statuses.Tabs[tn].TabType = MyCommon.TabUsageType.UserDefined;
1228 if (!AddNewTab(tn, true, _statuses.Tabs[tn].TabType, _statuses.Tabs[tn].ListInfo)) throw new Exception(Properties.Resources.TweenMain_LoadText1);
1231 this.JumpReadOpMenuItem.ShortcutKeyDisplayString = "Space";
1232 CopySTOTMenuItem.ShortcutKeyDisplayString = "Ctrl+C";
1233 CopyURLMenuItem.ShortcutKeyDisplayString = "Ctrl+Shift+C";
1234 CopyUserIdStripMenuItem.ShortcutKeyDisplayString = "Shift+Alt+C";
1236 if (SettingDialog.MinimizeToTray == false || this.WindowState != FormWindowState.Minimized)
1238 this.Visible = true;
1240 _curTab = ListTab.SelectedTab;
1242 _curList = (DetailsListView)_curTab.Tag;
1243 SetMainWindowTitle();
1244 SetNotifyIconText();
1246 if (SettingDialog.TabIconDisp)
1248 ListTab.DrawMode = TabDrawMode.Normal;
1252 ListTab.DrawMode = TabDrawMode.OwnerDrawFixed;
1253 ListTab.DrawItem += ListTab_DrawItem;
1254 ListTab.ImageList = null;
1257 _ignoreConfigSave = false;
1258 this.TweenMain_Resize(null, null);
1259 if (saveRequired) SaveConfigsAll(false);
1263 tw.VerifyCredentials();
1264 foreach (UserAccount ua in _cfgCommon.UserAccounts)
1266 if (ua.Username.ToLower() == tw.Username.ToLower())
1268 ua.UserId = tw.UserId;
1273 foreach (UserAccount ua in SettingDialog.UserAccounts)
1275 if (ua.UserId == 0 && ua.Username.ToLower() == tw.Username.ToLower())
1277 ua.UserId = tw.UserId;
1284 // 初回起動時だけ右下のメニューを目立たせる
1285 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))
1521 lst.VirtualListSize = tabInfo.AllCount; //リスト件数更新
1527 this.SelectListItem(lst,
1528 _statuses.IndexOf(tab.Text, selId[tab.Text]),
1529 _statuses.IndexOf(tab.Text, focusedId[tab.Text]));
1532 if (tabInfo.UnreadCount > 0)
1533 if (SettingDialog.TabIconDisp)
1534 if (tab.ImageIndex == -1) tab.ImageIndex = 0; //タブアイコン
1536 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
1540 //ex.Data["Msg"] = "Ref1, UseAPI=" + SettingDialog.UseAPI.ToString();
1549 if (befCnt != _curList.VirtualListSize)
1555 if (_curList.VirtualListSize > 0) _curList.EnsureVisible(0);
1559 if (_curList.VirtualListSize > 0) _curList.EnsureVisible(_curList.VirtualListSize - 1);
1566 if (_curList.VirtualListSize > 0 && _statuses.IndexOf(_curTab.Text, topId) > -1)
1568 _curList.EnsureVisible(_curList.VirtualListSize - 1);
1569 _curList.EnsureVisible(_statuses.IndexOf(_curTab.Text, topId));
1575 catch (Exception ex)
1577 ex.Data["Msg"] = "Ref2";
1583 NotifyNewPosts(notifyPosts,
1586 isMention || dmCount != _statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage).AllCount);
1588 SetMainWindowTitle();
1589 if (!StatusLabelUrl.Text.StartsWith("http")) SetStatusLabelUrl();
1591 HashSupl.AddRangeItem(tw.GetHashList());
1595 private long GetScrollPos(ref int smode)
1598 if (_curList != null && _curTab != null && _curList.VirtualListSize > 0)
1600 if (_statuses.SortMode == IdComparerClass.ComparerMode.Id)
1602 if (_statuses.SortOrder == SortOrder.Ascending)
1605 if (ListLockMenuItem.Checked)
1610 //if (_curList.TopItem != null) topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index);
1615 //最下行が表示されていたら、最下行へ強制スクロール。最下行が表示されていなかったら制御しない
1617 _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1); //一番下
1618 if (_item == null) _item = _curList.Items[_curList.Items.Count - 1];
1619 if (_item.Index == _curList.Items.Count - 1)
1626 //if (_curList.TopItem != null) topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index);
1634 if (ListLockMenuItem.Checked)
1637 if (_curList.TopItem != null) topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index);
1642 //最上行が表示されていたら、制御しない。最上行が表示されていなかったら、現在表示位置へ強制スクロール
1645 _item = _curList.GetItemAt(0, 10); //一番上
1646 if (_item == null) _item = _curList.Items[0];
1647 if (_item.Index == 0)
1653 if (_curList.TopItem != null) topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index);
1662 if (_curList.TopItem != null) topId = _statuses.GetId(_curTab.Text, _curList.TopItem.Index);
1673 private void SaveSelectedStatus(Dictionary<string, long[]> selId, Dictionary<string, long> focusedId)
1675 if (MyCommon._endingFlag) return;
1676 foreach (TabPage tab in ListTab.TabPages)
1678 DetailsListView lst = (DetailsListView)tab.Tag;
1679 if (lst.SelectedIndices.Count > 0 && lst.SelectedIndices.Count < 61)
1681 selId.Add(tab.Text, _statuses.GetId(tab.Text, lst.SelectedIndices));
1685 selId.Add(tab.Text, new long[1] {-2});
1687 if (lst.FocusedItem != null)
1688 focusedId.Add(tab.Text, _statuses.GetId(tab.Text, lst.FocusedItem.Index));
1690 focusedId.Add(tab.Text, -2);
1695 private bool BalloonRequired()
1697 Twitter.FormattedEvent ev = new Twitter.FormattedEvent();
1698 ev.Eventtype = MyCommon.EVENTTYPE.None;
1700 return BalloonRequired(ev);
1703 private bool IsEventNotifyAsEventType(MyCommon.EVENTTYPE type)
1705 return SettingDialog.EventNotifyEnabled && (type & SettingDialog.EventNotifyFlag) != 0 || type == MyCommon.EVENTTYPE.None;
1708 private bool IsMyEventNotityAsEventType(Twitter.FormattedEvent ev)
1710 return (ev.Eventtype & SettingDialog.IsMyEventNotifyFlag) != 0 ? true : !ev.IsMe;
1713 private bool BalloonRequired(Twitter.FormattedEvent ev)
1716 IsEventNotifyAsEventType(ev.Eventtype) && IsMyEventNotityAsEventType(ev) &&
1717 (NewPostPopMenuItem.Checked || (SettingDialog.ForceEventNotify && ev.Eventtype != MyCommon.EVENTTYPE.None)) &&
1721 SettingDialog.LimitBalloon &&
1723 this.WindowState == FormWindowState.Minimized ||
1725 Form.ActiveForm == null
1728 !SettingDialog.LimitBalloon
1731 !Win32Api.IsScreenSaverRunning())
1741 private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCount, bool newMentions)
1743 if (notifyPosts != null &&
1744 notifyPosts.Length > 0 &&
1745 this.SettingDialog.ReadOwnPost &&
1746 notifyPosts.All((post) => { return post.UserId == tw.UserId || post.ScreenName == tw.Username; }))
1752 if (BalloonRequired())
1754 if (notifyPosts != null && notifyPosts.Length > 0)
1756 //Growlは一個ずつばらして通知。ただし、3ポスト以上あるときはまとめる
1757 if (SettingDialog.IsNotifyUseGrowl)
1759 StringBuilder sb = new StringBuilder();
1763 foreach (PostClass post in notifyPosts)
1765 if (!(notifyPosts.Length > 3))
1771 if (post.IsReply && !post.IsExcludeReply) reply = true;
1772 if (post.IsDm) dm = true;
1773 if (sb.Length > 0) sb.Append(System.Environment.NewLine);
1774 switch (SettingDialog.NameBalloon)
1776 case MyCommon.NameBalloonEnum.UserID:
1777 sb.Append(post.ScreenName).Append(" : ");
1779 case MyCommon.NameBalloonEnum.NickName:
1780 sb.Append(post.Nickname).Append(" : ");
1783 sb.Append(post.TextFromApi);
1784 if (notifyPosts.Length > 3)
1786 if (notifyPosts.Last() != post) continue;
1789 StringBuilder title = new StringBuilder();
1790 GrowlHelper.NotifyType nt;
1791 if (SettingDialog.DispUsername)
1793 title.Append(tw.Username);
1794 title.Append(" - ");
1802 //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
1803 //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [DM] " + Properties.Resources.RefreshDirectMessageText1 + " " + addCount.ToString() + Properties.Resources.RefreshDirectMessageText2;
1804 title.Append(Application.ProductName);
1805 title.Append(" [DM] ");
1806 title.Append(Properties.Resources.RefreshDirectMessageText1);
1808 title.Append(addCount);
1809 title.Append(Properties.Resources.RefreshDirectMessageText2);
1810 nt = GrowlHelper.NotifyType.DirectMessage;
1814 //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
1815 //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [Reply!] " + Properties.Resources.RefreshTimelineText1 + " " + addCount.ToString() + Properties.Resources.RefreshTimelineText2;
1816 title.Append(Application.ProductName);
1817 title.Append(" [Reply!] ");
1818 title.Append(Properties.Resources.RefreshTimelineText1);
1820 title.Append(addCount);
1821 title.Append(Properties.Resources.RefreshTimelineText2);
1822 nt = GrowlHelper.NotifyType.Reply;
1826 //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info;
1827 //NotifyIcon1.BalloonTipTitle += Application.ProductName + " " + Properties.Resources.RefreshTimelineText1 + " " + addCount.ToString() + Properties.Resources.RefreshTimelineText2;
1828 title.Append(Application.ProductName);
1830 title.Append(Properties.Resources.RefreshTimelineText1);
1832 title.Append(addCount);
1833 title.Append(Properties.Resources.RefreshTimelineText2);
1834 nt = GrowlHelper.NotifyType.Notify;
1836 string bText = sb.ToString();
1837 if (string.IsNullOrEmpty(bText)) return;
1839 gh.Notify(nt, post.StatusId.ToString(), title.ToString(), bText, this.TIconDic[post.ImageUrl], 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;
1987 if (Tab.Equals(_curTab) && _itemCache != null && Index >= _itemCacheIndex && Index < _itemCacheIndex + _itemCache.Length)
1989 itm = _itemCache[Index - _itemCacheIndex];
1990 post = _postCache[Index - _itemCacheIndex];
1994 itm = ((DetailsListView)Tab.Tag).Items[Index];
1995 post = _statuses[Tab.Text, Index];
1998 ChangeItemStyleRead(Read, itm, post, ((DetailsListView)Tab.Tag));
2001 private void ChangeItemStyleRead(bool Read, ListViewItem Item, PostClass Post, DetailsListView DList)
2008 Item.SubItems[5].Text = "";
2013 Item.SubItems[5].Text = "★";
2019 else if (Post.RetweetedId > 0)
2021 else if (Post.IsOwl && (Post.IsDm || SettingDialog.OneWayLove))
2023 else if (Read || !SettingDialog.UseUnreadStyle)
2028 if (DList == null || Item.Index == -1)
2030 Item.ForeColor = cl;
2031 if (SettingDialog.UseUnreadStyle)
2037 if (SettingDialog.UseUnreadStyle)
2038 DList.ChangeItemFontAndColor(Item.Index, cl, fnt);
2040 DList.ChangeItemForeColor(Item.Index, cl);
2041 //if (_itemCache != null) DList.RedrawItems(_itemCacheIndex, _itemCacheIndex + _itemCache.Length - 1, false);
2045 private void ColorizeList()
2047 //Index:更新対象のListviewItem.Index。Colorを返す。
2048 //-1は全キャッシュ。Colorは返さない(ダミーを戻す)
2051 _post = _anchorPost;
2055 if (_itemCache == null) return;
2057 if (_post == null) return;
2061 for (int cnt = 0; cnt <= _itemCache.Length - 1; cnt++)
2063 _curList.ChangeItemBackColor(_itemCacheIndex + cnt, JudgeColor(_post, _postCache[cnt]));
2071 private void ColorizeList(ListViewItem Item, int Index)
2073 //Index:更新対象のListviewItem.Index。Colorを返す。
2074 //-1は全キャッシュ。Colorは返さない(ダミーを戻す)
2077 _post = _anchorPost;
2081 PostClass tPost = GetCurTabPost(Index);
2083 if (_post == null) return;
2085 if (Item.Index == -1)
2086 Item.BackColor = JudgeColor(_post, tPost);
2088 _curList.ChangeItemBackColor(Item.Index, JudgeColor(_post, tPost));
2091 private Color JudgeColor(PostClass BasePost, PostClass TargetPost)
2094 if (TargetPost.StatusId == BasePost.InReplyToStatusId)
2097 else if (TargetPost.IsMe)
2100 else if (TargetPost.IsReply)
2103 else if (BasePost.ReplyToList.Contains(TargetPost.ScreenName.ToLower()))
2105 cl = _clAtFromTarget;
2106 else if (TargetPost.ReplyToList.Contains(BasePost.ScreenName.ToLower()))
2109 else if (TargetPost.ScreenName.Equals(BasePost.ScreenName, StringComparison.OrdinalIgnoreCase))
2114 cl = _clListBackcolor;
2119 private void PostButton_Click(object sender, EventArgs e)
2121 if (StatusText.Text.Trim().Length == 0)
2123 if (!ImageSelectionPanel.Enabled)
2130 if (this.ExistCurrentPost && StatusText.Text.Trim() == string.Format("RT @{0}: {1}", _curPost.ScreenName, _curPost.TextFromApi))
2132 DialogResult rtResult = MessageBox.Show(string.Format(Properties.Resources.PostButton_Click1, Environment.NewLine),
2134 MessageBoxButtons.YesNoCancel,
2135 MessageBoxIcon.Question);
2138 case DialogResult.Yes:
2139 doReTweetOfficial(false);
2140 StatusText.Text = "";
2142 case DialogResult.Cancel:
2147 _history[_history.Count - 1] = new PostingStatus(StatusText.Text.Trim(), _reply_to_id, _reply_to_name);
2149 if (SettingDialog.Nicoms)
2151 StatusText.SelectionStart = StatusText.Text.Length;
2152 UrlConvert(MyCommon.UrlConverter.Nicoms);
2154 //if (SettingDialog.UrlConvertAuto)
2156 // StatusText.SelectionStart = StatusText.Text.Length;
2157 // UrlConvertAutoToolStripMenuItem_Click(null, null);
2159 //else if (SettingDialog.Nicoms)
2161 // StatusText.SelectionStart = StatusText.Text.Length;
2162 // UrlConvert(UrlConverter.Nicoms);
2164 StatusText.SelectionStart = StatusText.Text.Length;
2165 GetWorkerArg args = new GetWorkerArg();
2168 args.type = MyCommon.WORKERTYPE.PostMessage;
2169 CheckReplyTo(StatusText.Text);
2172 int adjustCount = 0;
2173 string tmpStatus = StatusText.Text.Trim();
2174 if (ToolStripMenuItemApiCommandEvasion.Checked)
2177 if (Regex.IsMatch(tmpStatus,
2178 @"^[+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]*(get|g|fav|follow|f|on|off|stop|quit|leave|l|whois|w|nudge|n|stats|invite|track|untrack|tracks|tracking|\*)([+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]+|$)",
2179 RegexOptions.IgnoreCase)
2180 && tmpStatus.EndsWith(" .") == false) adjustCount += 2;
2183 if (ToolStripMenuItemUrlMultibyteSplit.Checked)
2186 adjustCount += Regex.Matches(tmpStatus, @"https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#^]+").Count;
2189 bool isCutOff = false;
2190 bool isRemoveFooter = MyCommon.IsKeyDown(Keys.Shift);
2191 if (StatusText.Multiline && !SettingDialog.PostCtrlEnter)
2193 //複数行でEnter投稿の場合、Ctrlも押されていたらフッタ付加しない
2194 isRemoveFooter = MyCommon.IsKeyDown(Keys.Control);
2196 if (SettingDialog.PostShiftEnter)
2198 isRemoveFooter = MyCommon.IsKeyDown(Keys.Control);
2200 if (!isRemoveFooter && (StatusText.Text.Contains("RT @") || StatusText.Text.Contains("QT @")))
2202 isRemoveFooter = true;
2204 if (GetRestStatusCount(false, !isRemoveFooter) - adjustCount < 0)
2206 if (MessageBox.Show(Properties.Resources.PostLengthOverMessage1, Properties.Resources.PostLengthOverMessage2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.OK)
2209 //if (!SettingDialog.UrlConvertAuto) UrlConvertAutoToolStripMenuItem_Click(null, null);
2210 if (GetRestStatusCount(false, !isRemoveFooter) - adjustCount < 0)
2212 isRemoveFooter = true;
2223 if (StatusText.Text.StartsWith("D ") || StatusText.Text.StartsWith("d "))
2231 if (HashMgr.IsNotAddToAtReply)
2233 if (!string.IsNullOrEmpty(HashMgr.UseHash) && _reply_to_id == 0 && string.IsNullOrEmpty(_reply_to_name))
2236 header = HashMgr.UseHash + " ";
2238 footer = " " + HashMgr.UseHash;
2243 if (!string.IsNullOrEmpty(HashMgr.UseHash))
2246 header = HashMgr.UseHash + " ";
2248 footer = " " + HashMgr.UseHash;
2251 if (!isRemoveFooter)
2253 if (SettingDialog.UseRecommendStatus)
2255 footer += SettingDialog.RecommendStatusText;
2257 // テキストボックスに入力されている文字列を使用する
2258 footer += " " + SettingDialog.Status.Trim();
2261 args.status.status = header + StatusText.Text.Trim() + footer;
2263 if (ToolStripMenuItemApiCommandEvasion.Checked)
2266 if (Regex.IsMatch(args.status.status,
2267 @"^[+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]*(get|g|fav|follow|f|on|off|stop|quit|leave|l|whois|w|nudge|n|stats|invite|track|untrack|tracks|tracking|\*)([+\-\[\]\s\\.,*/(){}^~|='&%$#""<>?]+|$)",
2268 RegexOptions.IgnoreCase)
2269 && args.status.status.EndsWith(" .") == false) args.status.status += " .";
2272 if (ToolStripMenuItemUrlMultibyteSplit.Checked)
2275 Match mc2 = Regex.Match(args.status.status, @"https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#^]+");
2276 if (mc2.Success) args.status.status = Regex.Replace(args.status.status, @"https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#^]+", "$& ");
2279 if (IdeographicSpaceToSpaceToolStripMenuItem.Checked)
2281 // 文中の全角スペースを半角スペース1個にする
2282 args.status.status = args.status.status.Replace(" ", " ");
2285 if (isCutOff && args.status.status.Length > 140)
2287 args.status.status = args.status.status.Substring(0, 140);
2288 string AtId = @"(@|@)[a-z0-9_/]+$";
2289 string HashTag = @"(^|[^0-9A-Z&\/\?]+)(#|#)([0-9A-Z_]*[A-Z_]+)$";
2290 string Url = @"https?:\/\/[a-z0-9!\*'\(\);:&=\+\$\/%#\[\]\-_\.,~?]+$"; //簡易判定
2291 string pattern = string.Format("({0})|({1})|({2})", AtId, HashTag, Url);
2292 Match mc = Regex.Match(args.status.status, pattern, RegexOptions.IgnoreCase);
2295 //さらに@ID、ハッシュタグ、URLと推測される文字列をカットする
2296 args.status.status = args.status.status.Substring(0, 140 - mc.Value.Length);
2298 if (MessageBox.Show(args.status.status, "Post or Cancel?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel) return;
2301 args.status.inReplyToId = _reply_to_id;
2302 args.status.inReplyToName = _reply_to_name;
2303 if (ImageSelectionPanel.Visible)
2306 if (ImageSelectedPicture.Image != ImageSelectedPicture.InitialImage &&
2307 ImageServiceCombo.SelectedIndex > -1 &&
2308 !string.IsNullOrEmpty(ImagefilePathText.Text))
2310 if (MessageBox.Show(Properties.Resources.PostPictureConfirm1,
2311 Properties.Resources.PostPictureConfirm2,
2312 MessageBoxButtons.OKCancel,
2313 MessageBoxIcon.Question,
2314 MessageBoxDefaultButton.Button1)
2315 == DialogResult.Cancel)
2317 TimelinePanel.Visible = true;
2318 TimelinePanel.Enabled = true;
2319 ImageSelectionPanel.Visible = false;
2320 ImageSelectionPanel.Enabled = false;
2321 if (_curList != null)
2325 args.status.imageService = ImageServiceCombo.Text;
2326 args.status.imagePath = ImagefilePathText.Text;
2327 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
2328 ImagefilePathText.Text = "";
2329 TimelinePanel.Visible = true;
2330 TimelinePanel.Enabled = true;
2331 ImageSelectionPanel.Visible = false;
2332 ImageSelectionPanel.Enabled = false;
2333 if (_curList != null)
2338 MessageBox.Show(Properties.Resources.PostPictureWarn1, Properties.Resources.PostPictureWarn2);
2346 if (StatusText.Text.StartsWith("Google:", StringComparison.OrdinalIgnoreCase) && StatusText.Text.Trim().Length > 7)
2348 string tmp = string.Format(Properties.Resources.SearchItem2Url, HttpUtility.UrlEncode(StatusText.Text.Substring(7)));
2353 _reply_to_name = "";
2354 StatusText.Text = "";
2355 _history.Add(new PostingStatus());
2356 _hisIdx = _history.Count - 1;
2357 if (!ToolStripFocusLockMenuItem.Checked)
2358 ((Control)ListTab.SelectedTab.Tag).Focus();
2359 urlUndoBuffer = null;
2360 UrlUndoToolStripMenuItem.Enabled = false; //Undoをできないように設定
2363 private void EndToolStripMenuItem_Click(object sender, EventArgs e)
2365 MyCommon._endingFlag = true;
2369 private void Tween_FormClosing(object sender, FormClosingEventArgs e)
2371 if (!SettingDialog.CloseToExit && e.CloseReason == CloseReason.UserClosing && MyCommon._endingFlag == false)
2373 //_endingFlag=false:フォームの×ボタン
2375 this.Visible = false;
2379 //Google.GASender.GetInstance().TrackEventWithCategory("post", "end", tw.UserId);
2380 _hookGlobalHotkey.UnregisterAllOriginalHotkey();
2381 _ignoreConfigSave = true;
2382 MyCommon._endingFlag = true;
2383 TimerTimeline.Enabled = false;
2384 TimerRefreshIcon.Enabled = false;
2388 private void NotifyIcon1_BalloonTipClicked(object sender, EventArgs e)
2390 this.Visible = true;
2391 if (this.WindowState == FormWindowState.Minimized)
2393 this.WindowState = FormWindowState.Normal;
2396 this.BringToFront();
2399 private static int errorCount = 0;
2401 private static bool CheckAccountValid()
2403 if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid)
2409 Twitter.AccountState = MyCommon.ACCOUNT_STATE.Valid;
2418 private void GetTimelineWorker_DoWork(object sender, DoWorkEventArgs e)
2420 BackgroundWorker bw = (BackgroundWorker)sender;
2421 if (bw.CancellationPending || MyCommon._endingFlag)
2427 Thread.CurrentThread.Priority = ThreadPriority.BelowNormal;
2429 MyApplication.InitCulture();
2432 GetWorkerResult rslt = new GetWorkerResult();
2434 bool read = !SettingDialog.UnreadManage;
2435 if (_initial && SettingDialog.UnreadManage) read = SettingDialog.Readed;
2437 GetWorkerArg args = (GetWorkerArg)e.Argument;
2439 if (!CheckAccountValid())
2441 rslt.retMsg = "Auth error. Check your account";
2442 rslt.type = MyCommon.WORKERTYPE.ErrorState; //エラー表示のみ行ない、後処理キャンセル
2443 rslt.tName = args.tName;
2448 if (args.type != MyCommon.WORKERTYPE.OpenUri) bw.ReportProgress(0, ""); //Notifyアイコンアニメーション開始
2451 case MyCommon.WORKERTYPE.Timeline:
2452 case MyCommon.WORKERTYPE.Reply:
2453 bw.ReportProgress(50, MakeStatusMessage(args, false));
2454 ret = tw.GetTimelineApi(read, args.type, args.page == -1, _initial);
2456 if (string.IsNullOrEmpty(ret) && args.type == MyCommon.WORKERTYPE.Timeline && SettingDialog.ReadOldPosts)
2457 _statuses.SetRead();
2459 rslt.addCount = _statuses.DistributePosts();
2461 case MyCommon.WORKERTYPE.DirectMessegeRcv: //送信分もまとめて取得
2462 bw.ReportProgress(50, MakeStatusMessage(args, false));
2463 ret = tw.GetDirectMessageApi(read, MyCommon.WORKERTYPE.DirectMessegeRcv, args.page == -1);
2464 if (string.IsNullOrEmpty(ret)) ret = tw.GetDirectMessageApi(read, MyCommon.WORKERTYPE.DirectMessegeSnt, args.page == -1);
2465 rslt.addCount = _statuses.DistributePosts();
2467 case MyCommon.WORKERTYPE.FavAdd:
2469 if (_statuses.Tabs.ContainsKey(args.tName))
2471 TabClass tbc = _statuses.Tabs[args.tName];
2472 for (int i = 0; i <= args.ids.Count - 1; i++)
2474 PostClass post = null;
2475 if (tbc.IsInnerStorageTabType)
2476 post = tbc.Posts[args.ids[i]];
2478 post = _statuses[args.ids[i]];
2481 bw.ReportProgress(50, MakeStatusMessage(args, false));
2484 if (post.RetweetedId == 0)
2485 ret = tw.PostFavAdd(post.StatusId);
2487 ret = tw.PostFavAdd(post.RetweetedId);
2489 if (ret.Length == 0)
2491 args.sIds.Add(post.StatusId);
2492 post.IsFav = true; //リスト再描画必要
2493 _favTimestamps.Add(DateTime.Now);
2494 if (string.IsNullOrEmpty(post.RelTabName))
2496 //検索,リストUserTimeline.Relatedタブからのfavは、favタブへ追加せず。それ以外は追加
2497 _statuses.GetTabByType(MyCommon.TabUsageType.Favorites).Add(post.StatusId, post.IsRead, false);
2501 //検索,リスト,UserTimeline.Relatedタブからのfavで、TLでも取得済みならfav反映
2502 if (_statuses.ContainsKey(post.StatusId))
2504 PostClass postTl = _statuses[post.StatusId];
2505 postTl.IsFav = true;
2506 _statuses.GetTabByType(MyCommon.TabUsageType.Favorites).Add(postTl.StatusId, postTl.IsRead, false);
2509 //検索,リスト,UserTimeline,Relatedの各タブに反映
2510 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.PublicSearch | MyCommon.TabUsageType.Lists | MyCommon.TabUsageType.UserTimeline | MyCommon.TabUsageType.Related))
2512 if (tb.Contains(post.StatusId)) tb.Posts[post.StatusId].IsFav = true;
2518 rslt.sIds = args.sIds;
2520 case MyCommon.WORKERTYPE.FavRemove:
2522 if (_statuses.Tabs.ContainsKey(args.tName))
2524 TabClass tbc = _statuses.Tabs[args.tName];
2525 for (int i = 0; i <= args.ids.Count - 1; i++)
2527 PostClass post = null;
2528 if (tbc.IsInnerStorageTabType)
2529 post = tbc.Posts[args.ids[i]];
2531 post = _statuses[args.ids[i]];
2534 bw.ReportProgress(50, MakeStatusMessage(args, false));
2537 if (post.RetweetedId == 0)
2538 ret = tw.PostFavRemove(post.StatusId);
2540 ret = tw.PostFavRemove(post.RetweetedId);
2542 if (ret.Length == 0)
2544 args.sIds.Add(post.StatusId);
2545 post.IsFav = false; //リスト再描画必要
2546 if (_statuses.ContainsKey(post.StatusId)) _statuses[post.StatusId].IsFav = false;
2547 //検索,リスト,UserTimeline,Relatedの各タブに反映
2548 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.PublicSearch | MyCommon.TabUsageType.Lists | MyCommon.TabUsageType.UserTimeline | MyCommon.TabUsageType.Related))
2550 if (tb.Contains(post.StatusId)) tb.Posts[post.StatusId].IsFav = false;
2556 rslt.sIds = args.sIds;
2558 case MyCommon.WORKERTYPE.PostMessage:
2559 bw.ReportProgress(200);
2560 if (string.IsNullOrEmpty(args.status.imagePath))
2562 for (int i = 0; i <= 1; i++)
2564 ret = tw.PostStatus(args.status.status, args.status.inReplyToId);
2565 if (string.IsNullOrEmpty(ret) ||
2566 ret.StartsWith("OK:") ||
2567 ret.StartsWith("Outputz:") ||
2568 ret.StartsWith("Warn:") ||
2569 ret == "Err:Status is a duplicate." ||
2570 args.status.status.StartsWith("D", StringComparison.OrdinalIgnoreCase) ||
2571 args.status.status.StartsWith("DM", StringComparison.OrdinalIgnoreCase) ||
2572 Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid)
2578 ret = this.pictureService[args.status.imageService].Upload(ref args.status.imagePath,
2579 ref args.status.status,
2580 args.status.inReplyToId);
2582 bw.ReportProgress(300);
2583 rslt.status = args.status;
2585 case MyCommon.WORKERTYPE.Retweet:
2586 bw.ReportProgress(200);
2587 for (int i = 0; i <= args.ids.Count - 1; i++)
2589 ret = tw.PostRetweet(args.ids[i], read);
2591 bw.ReportProgress(300);
2593 case MyCommon.WORKERTYPE.Follower:
2594 bw.ReportProgress(50, Properties.Resources.UpdateFollowersMenuItem1_ClickText1);
2595 ret = tw.GetFollowersApi();
2596 if (string.IsNullOrEmpty(ret))
2598 ret = tw.GetNoRetweetIdsApi();
2601 case MyCommon.WORKERTYPE.Configuration:
2602 ret = tw.ConfigurationApi();
2604 case MyCommon.WORKERTYPE.OpenUri:
2605 string myPath = Convert.ToString(args.url);
2609 if (!string.IsNullOrEmpty(SettingDialog.BrowserPath))
2611 if (SettingDialog.BrowserPath.StartsWith("\"") && SettingDialog.BrowserPath.Length > 2 && SettingDialog.BrowserPath.IndexOf("\"", 2) > -1)
2613 int sep = SettingDialog.BrowserPath.IndexOf("\"", 2);
2614 string browserPath = SettingDialog.BrowserPath.Substring(1, sep - 1);
2616 if (sep < SettingDialog.BrowserPath.Length - 1)
2618 arg = SettingDialog.BrowserPath.Substring(sep + 1);
2620 myPath = arg + " " + myPath;
2621 System.Diagnostics.Process.Start(browserPath, myPath);
2625 System.Diagnostics.Process.Start(SettingDialog.BrowserPath, myPath);
2630 System.Diagnostics.Process.Start(myPath);
2635 // MessageBox.Show("ブラウザの起動に失敗、またはタイムアウトしました。" + ex.ToString());
2638 case MyCommon.WORKERTYPE.Favorites:
2639 bw.ReportProgress(50, MakeStatusMessage(args, false));
2640 ret = tw.GetFavoritesApi(read, args.type, args.page == -1);
2641 rslt.addCount = _statuses.DistributePosts();
2643 case MyCommon.WORKERTYPE.PublicSearch:
2644 bw.ReportProgress(50, MakeStatusMessage(args, false));
2645 if (string.IsNullOrEmpty(args.tName))
2647 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.PublicSearch))
2649 //if (!string.IsNullOrEmpty(tb.SearchWords)) ret = tw.GetPhoenixSearch(read, tb, false);
2650 if (!string.IsNullOrEmpty(tb.SearchWords)) ret = tw.GetSearch(read, tb, false);
2655 TabClass tb = _statuses.GetTabByName(args.tName);
2658 //ret = tw.GetPhoenixSearch(read, tb, false);
2659 ret = tw.GetSearch(read, tb, false);
2660 if (string.IsNullOrEmpty(ret) && args.page == -1)
2662 //ret = tw.GetPhoenixSearch(read, tb, true)
2663 ret = tw.GetSearch(read, tb, true);
2668 rslt.addCount = _statuses.DistributePosts();
2670 case MyCommon.WORKERTYPE.UserTimeline:
2671 bw.ReportProgress(50, MakeStatusMessage(args, false));
2673 if (SettingDialog.UseAdditionalCount) count = SettingDialog.UserTimelineCountApi;
2674 if (string.IsNullOrEmpty(args.tName))
2676 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.UserTimeline))
2678 if (!string.IsNullOrEmpty(tb.User)) ret = tw.GetUserTimelineApi(read, count, tb.User, tb, false);
2683 TabClass tb = _statuses.GetTabByName(args.tName);
2686 ret = tw.GetUserTimelineApi(read, count, tb.User, tb, args.page == -1);
2690 rslt.addCount = _statuses.DistributePosts();
2692 case MyCommon.WORKERTYPE.List:
2693 bw.ReportProgress(50, MakeStatusMessage(args, false));
2694 if (string.IsNullOrEmpty(args.tName))
2697 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.Lists))
2699 if (tb.ListInfo != null && tb.ListInfo.Id != 0) ret = tw.GetListStatus(read, tb, false, _initial);
2705 TabClass tb = _statuses.GetTabByName(args.tName);
2708 ret = tw.GetListStatus(read, tb, args.page == -1, _initial);
2712 rslt.addCount = _statuses.DistributePosts();
2714 case MyCommon.WORKERTYPE.Related:
2715 bw.ReportProgress(50, MakeStatusMessage(args, false));
2716 TabClass tab = _statuses.GetTabByName(args.tName);
2717 ret = tw.GetRelatedResult(read, tab);
2718 rslt.addCount = _statuses.DistributePosts();
2720 case MyCommon.WORKERTYPE.BlockIds:
2721 bw.ReportProgress(50, Properties.Resources.UpdateBlockUserText1);
2722 ret = tw.GetBlockUserIds();
2723 if (TabInformations.GetInstance().BlockIds.Count == 0)
2725 tw.GetBlockUserIds();
2730 if (bw.CancellationPending)
2737 if (args.type == MyCommon.WORKERTYPE.FavAdd)
2739 DateTime oneHour = DateTime.Now.Subtract(new TimeSpan(1, 0, 0));
2740 for (int i = _favTimestamps.Count - 1; i >= 0; i--)
2742 if (_favTimestamps[i].CompareTo(oneHour) < 0)
2744 _favTimestamps.RemoveAt(i);
2748 if (args.type == MyCommon.WORKERTYPE.Timeline && !_initial)
2752 DateTime tm = DateTime.Now;
2753 if (_tlTimestamps.ContainsKey(tm))
2754 _tlTimestamps[tm] += rslt.addCount;
2756 _tlTimestamps.Add(tm, rslt.addCount);
2758 DateTime oneHour = DateTime.Now.Subtract(new TimeSpan(1, 0, 0));
2759 List<DateTime> keys = new List<DateTime>();
2761 foreach (DateTime key in _tlTimestamps.Keys)
2763 if (key.CompareTo(oneHour) < 0)
2769 _tlCount += _tlTimestamps[key];
2772 foreach (DateTime key in keys)
2774 _tlTimestamps.Remove(key);
2781 if (args.type != MyCommon.WORKERTYPE.OpenUri) bw.ReportProgress(100, MakeStatusMessage(args, true)); //ステータス書き換え、Notifyアイコンアニメーション開始
2784 rslt.type = args.type;
2785 rslt.tName = args.tName;
2786 if (args.type == MyCommon.WORKERTYPE.DirectMessegeRcv ||
2787 args.type == MyCommon.WORKERTYPE.DirectMessegeSnt ||
2788 args.type == MyCommon.WORKERTYPE.Reply ||
2789 args.type == MyCommon.WORKERTYPE.Timeline ||
2790 args.type == MyCommon.WORKERTYPE.Favorites)
2792 rslt.page = args.page - 1; //値が正しいか後でチェック。10ページ毎の継続確認
2798 private string MakeStatusMessage(GetWorkerArg AsyncArg, bool Finish)
2804 switch (AsyncArg.type)
2806 case MyCommon.WORKERTYPE.Timeline:
2807 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText5 + AsyncArg.page.ToString() + Properties.Resources.GetTimelineWorker_RunWorkerCompletedText6;
2809 case MyCommon.WORKERTYPE.Reply:
2810 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText4 + AsyncArg.page.ToString() + Properties.Resources.GetTimelineWorker_RunWorkerCompletedText6;
2812 case MyCommon.WORKERTYPE.DirectMessegeRcv:
2813 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText8 + AsyncArg.page.ToString() + Properties.Resources.GetTimelineWorker_RunWorkerCompletedText6;
2815 case MyCommon.WORKERTYPE.FavAdd:
2816 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText15 + AsyncArg.page.ToString() + "/" + AsyncArg.ids.Count.ToString() +
2817 Properties.Resources.GetTimelineWorker_RunWorkerCompletedText16 + (AsyncArg.page - AsyncArg.sIds.Count - 1).ToString();
2819 case MyCommon.WORKERTYPE.FavRemove:
2820 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText17 + AsyncArg.page.ToString() + "/" + AsyncArg.ids.Count.ToString() +
2821 Properties.Resources.GetTimelineWorker_RunWorkerCompletedText18 + (AsyncArg.page - AsyncArg.sIds.Count - 1).ToString();
2823 case MyCommon.WORKERTYPE.Favorites:
2824 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText19;
2826 case MyCommon.WORKERTYPE.PublicSearch:
2827 smsg = "Search refreshing...";
2829 case MyCommon.WORKERTYPE.List:
2830 smsg = "List refreshing...";
2832 case MyCommon.WORKERTYPE.Related:
2833 smsg = "Related refreshing...";
2835 case MyCommon.WORKERTYPE.UserTimeline:
2836 smsg = "UserTimeline refreshing...";
2843 switch (AsyncArg.type)
2845 case MyCommon.WORKERTYPE.Timeline:
2846 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText1;
2848 case MyCommon.WORKERTYPE.Reply:
2849 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText9;
2851 case MyCommon.WORKERTYPE.DirectMessegeRcv:
2852 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText11;
2854 case MyCommon.WORKERTYPE.DirectMessegeSnt:
2855 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText13;
2857 case MyCommon.WORKERTYPE.FavAdd:
2860 case MyCommon.WORKERTYPE.FavRemove:
2863 case MyCommon.WORKERTYPE.Favorites:
2864 smsg = Properties.Resources.GetTimelineWorker_RunWorkerCompletedText20;
2866 case MyCommon.WORKERTYPE.Follower:
2867 smsg = Properties.Resources.UpdateFollowersMenuItem1_ClickText3;
2869 case MyCommon.WORKERTYPE.Configuration:
2872 case MyCommon.WORKERTYPE.PublicSearch:
2873 smsg = "Search refreshed";
2875 case MyCommon.WORKERTYPE.List:
2876 smsg = "List refreshed";
2878 case MyCommon.WORKERTYPE.Related:
2879 smsg = "Related refreshed";
2881 case MyCommon.WORKERTYPE.UserTimeline:
2882 smsg = "UserTimeline refreshed";
2884 case MyCommon.WORKERTYPE.BlockIds:
2885 smsg = Properties.Resources.UpdateBlockUserText3;
2892 private void GetTimelineWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
2894 if (MyCommon._endingFlag) return;
2895 if (e.ProgressPercentage > 100)
2898 if (e.ProgressPercentage == 200) //開始
2899 StatusLabel.Text = "Posting...";
2900 if (e.ProgressPercentage == 300) //終了
2901 StatusLabel.Text = Properties.Resources.PostWorker_RunWorkerCompletedText4;
2905 string smsg = (string)e.UserState;
2906 if (smsg.Length > 0) StatusLabel.Text = smsg;
2910 private void GetTimelineWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
2912 if (MyCommon._endingFlag || e.Cancelled) return; //キャンセル
2914 if (e.Error != null)
2916 _myStatusError = true;
2917 _waitTimeline = false;
2921 _waitPubSearch = false;
2922 _waitUserTimeline = false;
2924 throw new Exception("BackgroundWorker Exception", e.Error);
2927 GetWorkerResult rslt = (GetWorkerResult)e.Result;
2929 if (rslt.type == MyCommon.WORKERTYPE.OpenUri) return;
2932 if (rslt.retMsg.Length > 0)
2934 _myStatusError = true;
2935 StatusLabel.Text = rslt.retMsg;
2938 if (rslt.type == MyCommon.WORKERTYPE.ErrorState) return;
2940 if (rslt.type == MyCommon.WORKERTYPE.FavRemove)
2942 this.RemovePostFromFavTab(rslt.sIds.ToArray());
2946 //bool busy = false;
2947 //foreach (BackgroundWorker bw in _bw)
2949 // if (bw != null && bw.IsBusy)
2955 //if (!busy) RefreshTimeline(); //background処理なければ、リスト反映
2956 if (rslt.type == MyCommon.WORKERTYPE.Timeline ||
2957 rslt.type == MyCommon.WORKERTYPE.Reply ||
2958 rslt.type == MyCommon.WORKERTYPE.List ||
2959 rslt.type == MyCommon.WORKERTYPE.PublicSearch ||
2960 rslt.type == MyCommon.WORKERTYPE.DirectMessegeRcv ||
2961 rslt.type == MyCommon.WORKERTYPE.DirectMessegeSnt ||
2962 rslt.type == MyCommon.WORKERTYPE.Favorites ||
2963 rslt.type == MyCommon.WORKERTYPE.Follower ||
2964 rslt.type == MyCommon.WORKERTYPE.FavAdd ||
2965 rslt.type == MyCommon.WORKERTYPE.FavRemove ||
2966 rslt.type == MyCommon.WORKERTYPE.Related ||
2967 rslt.type == MyCommon.WORKERTYPE.UserTimeline ||
2968 rslt.type == MyCommon.WORKERTYPE.BlockIds ||
2969 rslt.type == MyCommon.WORKERTYPE.Configuration)
2971 RefreshTimeline(false); //リスト反映
2976 case MyCommon.WORKERTYPE.Timeline:
2977 _waitTimeline = false;
2980 // //API使用時の取得調整は別途考える(カウント調整?)
2983 case MyCommon.WORKERTYPE.Reply:
2985 if (rslt.newDM && !_initial)
2987 GetTimeline(MyCommon.WORKERTYPE.DirectMessegeRcv, 1, 0, "");
2990 case MyCommon.WORKERTYPE.Favorites:
2993 case MyCommon.WORKERTYPE.DirectMessegeRcv:
2996 case MyCommon.WORKERTYPE.FavAdd:
2997 case MyCommon.WORKERTYPE.FavRemove:
2998 if (_curList != null && _curTab != null)
3000 _curList.BeginUpdate();
3001 if (rslt.type == MyCommon.WORKERTYPE.FavRemove && _statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.Favorites)
3007 for (int i = 0; i <= rslt.sIds.Count - 1; i++)
3009 if (_curTab.Text.Equals(rslt.tName))
3011 int idx = _statuses.Tabs[rslt.tName].IndexOf(rslt.sIds[i]);
3014 PostClass post = null;
3015 TabClass tb = _statuses.Tabs[rslt.tName];
3018 if (tb.TabType == MyCommon.TabUsageType.Lists || tb.TabType == MyCommon.TabUsageType.PublicSearch)
3020 post = tb.Posts[rslt.sIds[i]];
3024 post = _statuses[rslt.sIds[i]];
3026 ChangeCacheStyleRead(post.IsRead, idx, _curTab);
3028 if (idx == _curItemIndex) DispSelectedPost(true); //選択アイテム再表示
3033 _curList.EndUpdate();
3036 case MyCommon.WORKERTYPE.PostMessage:
3037 if (string.IsNullOrEmpty(rslt.retMsg) ||
3038 rslt.retMsg.StartsWith("Outputz") ||
3039 rslt.retMsg.StartsWith("OK:") ||
3040 rslt.retMsg == "Warn:Status is a duplicate.")
3042 _postTimestamps.Add(DateTime.Now);
3043 DateTime oneHour = DateTime.Now.Subtract(new TimeSpan(1, 0, 0));
3044 for (int i = _postTimestamps.Count - 1; i >= 0; i--)
3046 if (_postTimestamps[i].CompareTo(oneHour) < 0)
3048 _postTimestamps.RemoveAt(i);
3052 if (!HashMgr.IsPermanent && !string.IsNullOrEmpty(HashMgr.UseHash))
3054 HashMgr.ClearHashtag();
3055 this.HashStripSplitButton.Text = "#[-]";
3056 this.HashToggleMenuItem.Checked = false;
3057 this.HashToggleToolStripMenuItem.Checked = false;
3059 SetMainWindowTitle();
3067 retry = MessageBox.Show(string.Format("{0} ---> [ " + rslt.retMsg + " ]" + Environment.NewLine + "\"" + rslt.status.status + "\"" + Environment.NewLine + "{1}",
3068 Properties.Resources.StatusUpdateFailed1,
3069 Properties.Resources.StatusUpdateFailed2),
3070 "Failed to update status",
3071 MessageBoxButtons.RetryCancel,
3072 MessageBoxIcon.Question);
3076 retry = DialogResult.Abort;
3078 if (retry == DialogResult.Retry)
3080 GetWorkerArg args = new GetWorkerArg();
3083 args.type = MyCommon.WORKERTYPE.PostMessage;
3084 args.status = rslt.status;
3089 if (ToolStripFocusLockMenuItem.Checked)
3091 //連投モードのときだけEnterイベントが起きないので強制的に背景色を戻す
3092 StatusText_Enter(StatusText, new EventArgs());
3096 if (rslt.retMsg.Length == 0 && SettingDialog.PostAndGet)
3098 if (_isActiveUserstream)
3100 RefreshTimeline(true);
3104 GetTimeline(MyCommon.WORKERTYPE.Timeline, 1, 0, "");
3108 case MyCommon.WORKERTYPE.Retweet:
3109 if (rslt.retMsg.Length == 0)
3111 _postTimestamps.Add(DateTime.Now);
3112 DateTime oneHour = DateTime.Now.Subtract(new TimeSpan(1, 0, 0));
3113 for (int i = _postTimestamps.Count - 1; i >= 0; i--)
3115 if (_postTimestamps[i].CompareTo(oneHour) < 0)
3117 _postTimestamps.RemoveAt(i);
3120 if (!_isActiveUserstream && SettingDialog.PostAndGet) GetTimeline(MyCommon.WORKERTYPE.Timeline, 1, 0, "");
3123 case MyCommon.WORKERTYPE.Follower:
3124 //_waitFollower = false;
3127 if (_curList != null) _curList.Refresh();
3129 case MyCommon.WORKERTYPE.Configuration:
3130 //_waitFollower = false
3131 if (SettingDialog.TwitterConfiguration.PhotoSizeLimit != 0)
3133 pictureService["Twitter"].Configuration("MaxUploadFilesize", SettingDialog.TwitterConfiguration.PhotoSizeLimit);
3137 if (_curList != null) _curList.Refresh();
3139 case MyCommon.WORKERTYPE.PublicSearch:
3140 _waitPubSearch = false;
3142 case MyCommon.WORKERTYPE.UserTimeline:
3143 _waitUserTimeline = false;
3145 case MyCommon.WORKERTYPE.List:
3148 case MyCommon.WORKERTYPE.Related:
3149 TabClass tab = _statuses.GetTabByType(MyCommon.TabUsageType.Related);
3150 if (tab != null && tab.RelationTargetPost != null && tab.Contains(tab.RelationTargetPost.StatusId))
3152 foreach (TabPage tp in ListTab.TabPages)
3154 if (tp.Text == tab.TabName)
3156 ((DetailsListView)tp.Tag).SelectedIndices.Add(tab.IndexOf(tab.RelationTargetPost.StatusId));
3157 ((DetailsListView)tp.Tag).Items[tab.IndexOf(tab.RelationTargetPost.StatusId)].Focused = true;
3166 private void RemovePostFromFavTab(Int64[] ids)
3168 string favTabName = _statuses.GetTabByType(MyCommon.TabUsageType.Favorites).TabName;
3170 if (_curTab.Text.Equals(favTabName))
3172 if (_curList.FocusedItem != null)
3173 fidx = _curList.FocusedItem.Index;
3174 else if (_curList.TopItem != null)
3175 fidx = _curList.TopItem.Index;
3180 foreach (long i in ids)
3184 _statuses.RemoveFavPost(i);
3191 if (_curTab != null && _curTab.Text.Equals(favTabName))
3193 _itemCache = null; //キャッシュ破棄
3196 //_curItemIndex = -1;
3198 foreach (TabPage tp in ListTab.TabPages)
3200 if (tp.Text == favTabName)
3202 ((DetailsListView)tp.Tag).VirtualListSize = _statuses.Tabs[favTabName].AllCount;
3206 if (_curTab.Text.Equals(favTabName))
3210 _curList.SelectedIndices.Clear();
3212 while (_curList.SelectedIndices.Count > 0);
3214 if (_statuses.Tabs[favTabName].AllCount > 0)
3216 if (_statuses.Tabs[favTabName].AllCount - 1 > fidx && fidx > -1)
3218 _curList.SelectedIndices.Add(fidx);
3222 _curList.SelectedIndices.Add(_statuses.Tabs[favTabName].AllCount - 1);
3224 if (_curList.SelectedIndices.Count > 0)
3226 _curList.EnsureVisible(_curList.SelectedIndices[0]);
3227 _curList.FocusedItem = _curList.Items[_curList.SelectedIndices[0]];
3233 private static Dictionary<MyCommon.WORKERTYPE, DateTime> lastTime = new Dictionary<MyCommon.WORKERTYPE, DateTime>();
3235 private void GetTimeline(MyCommon.WORKERTYPE WkType, int fromPage, int toPage, string tabName)
3237 if (!this.IsNetworkAvailable()) return;
3240 GetWorkerArg args = new GetWorkerArg();
3241 args.page = fromPage;
3242 args.endPage = toPage;
3244 args.tName = tabName;
3246 if (!lastTime.ContainsKey(WkType)) lastTime.Add(WkType, new DateTime());
3247 double period = DateTime.Now.Subtract(lastTime[WkType]).TotalSeconds;
3248 if (period > 1 || period < -1)
3250 lastTime[WkType] = DateTime.Now;
3254 //Timeline取得モードの場合はReplyも同時に取得
3255 //if (!SettingDialog.UseAPI &&
3257 // WkType == MyCommon.WORKERTYPE.Timeline &&
3258 // SettingDialog.CheckReply)
3260 // //TimerReply.Enabled = false;
3261 // _mentionCounter = SettingDialog.ReplyPeriodInt;
3262 // GetWorkerArg _args = new GetWorkerArg();
3263 // _args.page = fromPage;
3264 // _args.endPage = toPage;
3265 // _args.type = MyCommon.WORKERTYPE.Reply;
3270 private void NotifyIcon1_MouseClick(object sender, MouseEventArgs e)
3272 if (e.Button == MouseButtons.Left)
3274 this.Visible = true;
3275 if (this.WindowState == FormWindowState.Minimized)
3277 this.WindowState = _formWindowState;
3280 this.BringToFront();
3284 private void MyList_MouseDoubleClick(object sender, MouseEventArgs e)
3286 switch (SettingDialog.ListDoubleClickAction)
3289 MakeReplyOrDirectStatus();
3292 FavoriteChange(true);
3295 if (_curPost != null)
3296 ShowUserStatus(_curPost.ScreenName, false);
3302 ShowRelatedStatusesMenuItem_Click(null, null);
3305 MoveToHomeToolStripMenuItem_Click(null, null);
3308 StatusOpenMenuItem_Click(null, null);
3316 private void FavAddToolStripMenuItem_Click(object sender, EventArgs e)
3318 FavoriteChange(true);
3321 private void FavRemoveToolStripMenuItem_Click(object sender, EventArgs e)
3323 FavoriteChange(false);
3327 private void FavoriteRetweetMenuItem_Click(object sender, EventArgs e)
3329 FavoritesRetweetOriginal();
3332 private void FavoriteRetweetUnofficialMenuItem_Click(object sender, EventArgs e)
3334 FavoritesRetweetUnofficial();
3337 private void FavoriteChange(bool FavAdd , bool multiFavoriteChangeDialogEnable = true)
3339 //trueでFavAdd,falseでFavRemove
3340 if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage || _curList.SelectedIndices.Count == 0
3341 || !this.ExistCurrentPost) return;
3344 if (_curList.SelectedIndices.Count > 250 && FavAdd)
3346 MessageBox.Show(Properties.Resources.FavoriteLimitCountText);
3347 _DoFavRetweetFlags = false;
3350 else if (multiFavoriteChangeDialogEnable && _curList.SelectedIndices.Count > 1)
3354 string QuestionText = Properties.Resources.FavAddToolStripMenuItem_ClickText1;
3355 if (_DoFavRetweetFlags) QuestionText = Properties.Resources.FavoriteRetweetQuestionText3;
3356 if (MessageBox.Show(QuestionText, Properties.Resources.FavAddToolStripMenuItem_ClickText2,
3357 MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
3359 _DoFavRetweetFlags = false;
3365 if (MessageBox.Show(Properties.Resources.FavRemoveToolStripMenuItem_ClickText1, Properties.Resources.FavRemoveToolStripMenuItem_ClickText2,
3366 MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
3373 GetWorkerArg args = new GetWorkerArg();
3374 args.ids = new List<long>();
3375 args.sIds = new List<long>();
3376 args.tName = _curTab.Text;
3379 args.type = MyCommon.WORKERTYPE.FavAdd;
3383 args.type = MyCommon.WORKERTYPE.FavRemove;
3385 foreach (int idx in _curList.SelectedIndices)
3387 PostClass post = GetCurTabPost(idx);
3390 if (!post.IsFav) args.ids.Add(post.StatusId);
3394 if (post.IsFav) args.ids.Add(post.StatusId);
3397 if (args.ids.Count == 0)
3400 StatusLabel.Text = Properties.Resources.FavAddToolStripMenuItem_ClickText4;
3402 StatusLabel.Text = Properties.Resources.FavRemoveToolStripMenuItem_ClickText4;
3410 private PostClass GetCurTabPost(int Index)
3412 if (_postCache != null && Index >= _itemCacheIndex && Index < _itemCacheIndex + _postCache.Length)
3413 return _postCache[Index - _itemCacheIndex];
3415 return _statuses[_curTab.Text, Index];
3419 private void MoveToHomeToolStripMenuItem_Click(object sender, EventArgs e)
3421 if (_curList.SelectedIndices.Count > 0)
3422 OpenUriAsync(MyCommon.TwitterUrl + GetCurTabPost(_curList.SelectedIndices[0]).ScreenName);
3423 else if (_curList.SelectedIndices.Count == 0)
3424 OpenUriAsync(MyCommon.TwitterUrl);
3427 private void MoveToFavToolStripMenuItem_Click(object sender, EventArgs e)
3429 if (_curList.SelectedIndices.Count > 0)
3430 OpenUriAsync(MyCommon.TwitterUrl + "#!/" + GetCurTabPost(_curList.SelectedIndices[0]).ScreenName + "/favorites");
3433 private void Tween_ClientSizeChanged(object sender, EventArgs e)
3435 if ((!_initialLayout) && this.Visible)
3437 if (this.WindowState == FormWindowState.Normal)
3439 _mySize = this.ClientSize;
3440 _mySpDis = this.SplitContainer1.SplitterDistance;
3441 _mySpDis3 = this.SplitContainer3.SplitterDistance;
3442 if (StatusText.Multiline) _mySpDis2 = this.StatusText.Height;
3443 _modifySettingLocal = true;
3448 private void MyList_ColumnClick(object sender, ColumnClickEventArgs e)
3450 if (SettingDialog.SortOrderLock) return;
3451 IdComparerClass.ComparerMode mode = IdComparerClass.ComparerMode.Id;
3454 mode = IdComparerClass.ComparerMode.Id;
3462 case 6: //0:アイコン,5:未読マーク,6:プロテクト・フィルターマーク
3466 mode = IdComparerClass.ComparerMode.Nickname;
3469 mode = IdComparerClass.ComparerMode.Data;
3472 mode = IdComparerClass.ComparerMode.Id;
3475 mode = IdComparerClass.ComparerMode.Name;
3478 mode = IdComparerClass.ComparerMode.Source;
3482 _statuses.ToggleSortOrder(mode);
3485 DetailsListView list = (DetailsListView)sender;
3488 list.Columns[0].Text = ColumnOrgText[0];
3489 list.Columns[1].Text = ColumnText[2];
3493 for (int i = 0; i <= 7; i++)
3495 list.Columns[i].Text = ColumnOrgText[i];
3497 list.Columns[e.Column].Text = ColumnText[e.Column];
3503 if (_statuses.Tabs[_curTab.Text].AllCount > 0 && _curPost != null)
3505 int idx = _statuses.Tabs[_curTab.Text].IndexOf(_curPost.StatusId);
3508 SelectListItem(_curList, idx);
3509 _curList.EnsureVisible(idx);
3513 _modifySettingCommon = true;
3516 private void Tween_LocationChanged(object sender, EventArgs e)
3518 if (this.WindowState == FormWindowState.Normal && !_initialLayout)
3520 _myLoc = this.DesktopLocation;
3521 _modifySettingLocal = true;
3525 private void ContextMenuOperate_Opening(object sender, CancelEventArgs e)
3527 if (ListTab.SelectedTab == null) return;
3528 if (_statuses == null || _statuses.Tabs == null || !_statuses.Tabs.ContainsKey(ListTab.SelectedTab.Text)) return;
3529 if (!this.ExistCurrentPost)
3531 ReplyStripMenuItem.Enabled = false;
3532 ReplyAllStripMenuItem.Enabled = false;
3533 DMStripMenuItem.Enabled = false;
3534 ShowProfileMenuItem.Enabled = false;
3535 ShowUserTimelineContextMenuItem.Enabled = false;
3536 ListManageUserContextToolStripMenuItem2.Enabled = false;
3537 MoveToFavToolStripMenuItem.Enabled = false;
3538 TabMenuItem.Enabled = false;
3539 IDRuleMenuItem.Enabled = false;
3540 ReadedStripMenuItem.Enabled = false;
3541 UnreadStripMenuItem.Enabled = false;
3545 ShowProfileMenuItem.Enabled = true;
3546 ListManageUserContextToolStripMenuItem2.Enabled = true;
3547 ReplyStripMenuItem.Enabled = true;
3548 ReplyAllStripMenuItem.Enabled = true;
3549 DMStripMenuItem.Enabled = true;
3550 ShowUserTimelineContextMenuItem.Enabled = true;
3551 MoveToFavToolStripMenuItem.Enabled = true;
3552 TabMenuItem.Enabled = true;
3553 IDRuleMenuItem.Enabled = true;
3554 ReadedStripMenuItem.Enabled = true;
3555 UnreadStripMenuItem.Enabled = true;
3557 DeleteStripMenuItem.Text = Properties.Resources.DeleteMenuText1;
3558 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.DirectMessage || !this.ExistCurrentPost || _curPost.IsDm)
3560 FavAddToolStripMenuItem.Enabled = false;
3561 FavRemoveToolStripMenuItem.Enabled = false;
3562 StatusOpenMenuItem.Enabled = false;
3563 FavorareMenuItem.Enabled = false;
3564 ShowRelatedStatusesMenuItem.Enabled = false;
3566 ReTweetStripMenuItem.Enabled = false;
3567 ReTweetOriginalStripMenuItem.Enabled = false;
3568 QuoteStripMenuItem.Enabled = false;
3569 FavoriteRetweetContextMenu.Enabled = false;
3570 FavoriteRetweetUnofficialContextMenu.Enabled = false;
3571 if (this.ExistCurrentPost && _curPost.IsDm)
3572 DeleteStripMenuItem.Enabled = true;
3574 DeleteStripMenuItem.Enabled = false;
3578 FavAddToolStripMenuItem.Enabled = true;
3579 FavRemoveToolStripMenuItem.Enabled = true;
3580 StatusOpenMenuItem.Enabled = true;
3581 FavorareMenuItem.Enabled = true;
3582 ShowRelatedStatusesMenuItem.Enabled = true; //PublicSearchの時問題出るかも
3586 ReTweetOriginalStripMenuItem.Enabled = false;
3587 FavoriteRetweetContextMenu.Enabled = false;
3588 if (string.IsNullOrEmpty(_curPost.RetweetedBy))
3590 DeleteStripMenuItem.Text = Properties.Resources.DeleteMenuText1;
3594 DeleteStripMenuItem.Text = Properties.Resources.DeleteMenuText2;
3596 DeleteStripMenuItem.Enabled = true;
3600 if (string.IsNullOrEmpty(_curPost.RetweetedBy))
3602 DeleteStripMenuItem.Text = Properties.Resources.DeleteMenuText1;
3606 DeleteStripMenuItem.Text = Properties.Resources.DeleteMenuText2;
3608 DeleteStripMenuItem.Enabled = false;
3609 if (_curPost.IsProtect)
3611 ReTweetOriginalStripMenuItem.Enabled = false;
3612 ReTweetStripMenuItem.Enabled = false;
3613 QuoteStripMenuItem.Enabled = false;
3614 FavoriteRetweetContextMenu.Enabled = false;
3615 FavoriteRetweetUnofficialContextMenu.Enabled = false;
3619 ReTweetOriginalStripMenuItem.Enabled = true;
3620 ReTweetStripMenuItem.Enabled = true;
3621 QuoteStripMenuItem.Enabled = true;
3622 FavoriteRetweetContextMenu.Enabled = true;
3623 FavoriteRetweetUnofficialContextMenu.Enabled = true;
3627 //if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType != MyCommon.TabUsageType.Favorites)
3629 // RefreshMoreStripMenuItem.Enabled = true;
3633 // RefreshMoreStripMenuItem.Enabled = false;
3635 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.PublicSearch
3636 || !this.ExistCurrentPost
3637 || !(_curPost.InReplyToStatusId > 0))
3639 RepliedStatusOpenMenuItem.Enabled = false;
3643 RepliedStatusOpenMenuItem.Enabled = true;
3645 if (!this.ExistCurrentPost || string.IsNullOrEmpty(_curPost.RetweetedBy))
3647 MoveToRTHomeMenuItem.Enabled = false;
3651 MoveToRTHomeMenuItem.Enabled = true;
3655 private void ReplyStripMenuItem_Click(object sender, EventArgs e)
3657 MakeReplyOrDirectStatus(false, true);
3660 private void DMStripMenuItem_Click(object sender, EventArgs e)
3662 MakeReplyOrDirectStatus(false, false);
3665 private void doStatusDelete()
3667 if (_curTab == null || _curList == null) return;
3668 if (_statuses.Tabs[_curTab.Text].TabType != MyCommon.TabUsageType.DirectMessage)
3670 bool myPost = false;
3671 foreach (int idx in _curList.SelectedIndices)
3673 if (GetCurTabPost(idx).IsMe ||
3674 GetCurTabPost(idx).RetweetedBy.ToLower() == tw.Username.ToLower())
3680 if (!myPost) return;
3684 if (_curList.SelectedIndices.Count == 0)
3688 string tmp = string.Format(Properties.Resources.DeleteStripMenuItem_ClickText1, Environment.NewLine);
3690 if (MessageBox.Show(tmp, Properties.Resources.DeleteStripMenuItem_ClickText2,
3691 MessageBoxButtons.OKCancel,
3692 MessageBoxIcon.Question) == DialogResult.Cancel) return;
3695 if (_curList.FocusedItem != null)
3696 fidx = _curList.FocusedItem.Index;
3697 else if (_curList.TopItem != null)
3698 fidx = _curList.TopItem.Index;
3704 this.Cursor = Cursors.WaitCursor;
3707 foreach (long Id in _statuses.GetId(_curTab.Text, _curList.SelectedIndices))
3710 if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage)
3712 rtn = tw.RemoveDirectMessage(Id, _statuses[Id]);
3716 if (_statuses[Id].IsMe || _statuses[Id].RetweetedBy.ToLower() == tw.Username.ToLower())
3717 rtn = tw.RemoveStatus(Id);
3728 _statuses.RemovePost(Id);
3733 StatusLabel.Text = Properties.Resources.DeleteStripMenuItem_ClickText3; //失敗
3735 StatusLabel.Text = Properties.Resources.DeleteStripMenuItem_ClickText4; //成功
3737 _itemCache = null; //キャッシュ破棄
3741 foreach (TabPage tb in ListTab.TabPages)
3743 ((DetailsListView)tb.Tag).VirtualListSize = _statuses.Tabs[tb.Text].AllCount;
3744 if (_curTab.Equals(tb))
3748 _curList.SelectedIndices.Clear();
3750 while (_curList.SelectedIndices.Count > 0);
3752 if (_statuses.Tabs[tb.Text].AllCount > 0)
3754 if (_statuses.Tabs[tb.Text].AllCount - 1 > fidx && fidx > -1)
3755 _curList.SelectedIndices.Add(fidx);
3757 _curList.SelectedIndices.Add(_statuses.Tabs[tb.Text].AllCount - 1);
3759 if (_curList.SelectedIndices.Count > 0)
3761 _curList.EnsureVisible(_curList.SelectedIndices[0]);
3762 _curList.FocusedItem = _curList.Items[_curList.SelectedIndices[0]];
3766 if (_statuses.Tabs[tb.Text].UnreadCount == 0)
3768 if (SettingDialog.TabIconDisp)
3770 if (tb.ImageIndex == 0) tb.ImageIndex = -1; //タブアイコン
3774 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
3778 this.Cursor = Cursors.Default;
3782 private void DeleteStripMenuItem_Click(object sender, EventArgs e)
3787 private void ReadedStripMenuItem_Click(object sender, EventArgs e)
3789 _curList.BeginUpdate();
3790 if (SettingDialog.UnreadManage)
3792 foreach (int idx in _curList.SelectedIndices)
3794 _statuses.SetReadAllTab(true, _curTab.Text, idx);
3797 foreach (int idx in _curList.SelectedIndices)
3799 ChangeCacheStyleRead(true, idx, _curTab);
3802 _curList.EndUpdate();
3803 foreach (TabPage tb in ListTab.TabPages)
3805 if (_statuses.Tabs[tb.Text].UnreadCount == 0)
3807 if (SettingDialog.TabIconDisp)
3809 if (tb.ImageIndex == 0) tb.ImageIndex = -1; //タブアイコン
3813 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
3816 private void UnreadStripMenuItem_Click(object sender, EventArgs e)
3818 _curList.BeginUpdate();
3819 if (SettingDialog.UnreadManage)
3821 foreach (int idx in _curList.SelectedIndices)
3823 _statuses.SetReadAllTab(false, _curTab.Text, idx);
3826 foreach (int idx in _curList.SelectedIndices)
3828 ChangeCacheStyleRead(false, idx, _curTab);
3831 _curList.EndUpdate();
3832 foreach (TabPage tb in ListTab.TabPages)
3834 if (_statuses.Tabs[tb.Text].UnreadCount > 0)
3836 if (SettingDialog.TabIconDisp)
3838 if (tb.ImageIndex == -1) tb.ImageIndex = 0; //タブアイコン
3842 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
3845 private void RefreshStripMenuItem_Click(object sender, EventArgs e)
3850 private void DoRefresh()
3852 if (_curTab != null)
3854 switch (_statuses.Tabs[_curTab.Text].TabType)
3856 case MyCommon.TabUsageType.Mentions:
3857 GetTimeline(MyCommon.WORKERTYPE.Reply, 1, 0, "");
3859 case MyCommon.TabUsageType.DirectMessage:
3860 GetTimeline(MyCommon.WORKERTYPE.DirectMessegeRcv, 1, 0, "");
3862 case MyCommon.TabUsageType.Favorites:
3863 GetTimeline(MyCommon.WORKERTYPE.Favorites, 1, 0, "");
3865 //case MyCommon.TabUsageType.Profile:
3867 case MyCommon.TabUsageType.PublicSearch:
3869 TabClass tb = _statuses.Tabs[_curTab.Text];
3870 if (string.IsNullOrEmpty(tb.SearchWords)) return;
3871 GetTimeline(MyCommon.WORKERTYPE.PublicSearch, 1, 0, _curTab.Text);
3873 case MyCommon.TabUsageType.UserTimeline:
3874 GetTimeline(MyCommon.WORKERTYPE.UserTimeline, 1, 0, _curTab.Text);
3876 case MyCommon.TabUsageType.Lists:
3878 TabClass tab = _statuses.Tabs[_curTab.Text];
3879 if (tab.ListInfo == null || tab.ListInfo.Id == 0) return;
3880 GetTimeline(MyCommon.WORKERTYPE.List, 1, 0, _curTab.Text);
3883 GetTimeline(MyCommon.WORKERTYPE.Timeline, 1, 0, "");
3889 GetTimeline(MyCommon.WORKERTYPE.Timeline, 1, 0, "");
3893 private void DoRefreshMore()
3896 if (_curTab != null)
3898 switch (_statuses.Tabs[_curTab.Text].TabType)
3900 case MyCommon.TabUsageType.Mentions:
3901 GetTimeline(MyCommon.WORKERTYPE.Reply, -1, 0, "");
3903 case MyCommon.TabUsageType.DirectMessage:
3904 GetTimeline(MyCommon.WORKERTYPE.DirectMessegeRcv, -1, 0, "");
3906 case MyCommon.TabUsageType.Favorites:
3907 GetTimeline(MyCommon.WORKERTYPE.Favorites, -1, 0, "");
3909 case MyCommon.TabUsageType.Profile:
3912 case MyCommon.TabUsageType.PublicSearch:
3914 TabClass tb = _statuses.Tabs[_curTab.Text];
3915 if (string.IsNullOrEmpty(tb.SearchWords)) return;
3916 GetTimeline(MyCommon.WORKERTYPE.PublicSearch, -1, 0, _curTab.Text);
3918 case MyCommon.TabUsageType.UserTimeline:
3919 GetTimeline(MyCommon.WORKERTYPE.UserTimeline, -1, 0, _curTab.Text);
3921 case MyCommon.TabUsageType.Lists:
3923 TabClass tab = _statuses.Tabs[_curTab.Text];
3924 if (tab.ListInfo == null || tab.ListInfo.Id == 0) return;
3925 GetTimeline(MyCommon.WORKERTYPE.List, -1, 0, _curTab.Text);
3928 GetTimeline(MyCommon.WORKERTYPE.Timeline, -1, 0, "");
3934 GetTimeline(MyCommon.WORKERTYPE.Timeline, -1, 0, "");
3938 private void SettingStripMenuItem_Click(object sender, EventArgs e)
3940 DialogResult result;
3941 string uid = tw.Username.ToLower();
3945 result = SettingDialog.ShowDialog(this);
3952 if (result == DialogResult.OK)
3956 tw.TinyUrlResolve = SettingDialog.TinyUrlResolve;
3957 tw.RestrictFavCheck = SettingDialog.RestrictFavCheck;
3958 tw.ReadOwnPost = SettingDialog.ReadOwnPost;
3959 tw.UseSsl = SettingDialog.UseSsl;
3960 ShortUrl.IsResolve = SettingDialog.TinyUrlResolve;
3961 ShortUrl.IsForceResolve = SettingDialog.ShortUrlForceResolve;
3962 ShortUrl.BitlyId = SettingDialog.BitlyUser;
3963 ShortUrl.BitlyKey = SettingDialog.BitlyPwd;
3964 HttpTwitter.TwitterUrl = _cfgCommon.TwitterUrl;
3965 HttpTwitter.TwitterSearchUrl = _cfgCommon.TwitterSearchUrl;
3967 HttpConnection.InitializeConnection(SettingDialog.DefaultTimeOut,
3968 SettingDialog.SelectedProxyType,
3969 SettingDialog.ProxyAddress,
3970 SettingDialog.ProxyPort,
3971 SettingDialog.ProxyUser,
3972 SettingDialog.ProxyPassword);
3973 this.CreatePictureServices();
3975 this.SplitContainer4.Panel2.Controls.RemoveAt(0);
3976 this.ab = new AdsBrowser();
3977 this.SplitContainer4.Panel2.Controls.Add(ab);
3981 if (SettingDialog.TabIconDisp)
3983 ListTab.DrawItem -= ListTab_DrawItem;
3984 ListTab.DrawMode = TabDrawMode.Normal;
3985 ListTab.ImageList = this.TabImage;
3989 ListTab.DrawItem -= ListTab_DrawItem;
3990 ListTab.DrawItem += ListTab_DrawItem;
3991 ListTab.DrawMode = TabDrawMode.OwnerDrawFixed;
3992 ListTab.ImageList = null;
3995 catch (Exception ex)
3997 ex.Data["Instance"] = "ListTab(TabIconDisp)";
3998 ex.Data["IsTerminatePermission"] = false;
4004 if (!SettingDialog.UnreadManage)
4006 ReadedStripMenuItem.Enabled = false;
4007 UnreadStripMenuItem.Enabled = false;
4008 if (SettingDialog.TabIconDisp)
4010 foreach (TabPage myTab in ListTab.TabPages)
4012 myTab.ImageIndex = -1;
4018 ReadedStripMenuItem.Enabled = true;
4019 UnreadStripMenuItem.Enabled = true;
4022 catch (Exception ex)
4024 ex.Data["Instance"] = "ListTab(UnreadManage)";
4025 ex.Data["IsTerminatePermission"] = false;
4031 foreach (TabPage mytab in ListTab.TabPages)
4033 DetailsListView lst = (DetailsListView)mytab.Tag;
4034 lst.GridLines = SettingDialog.ShowGrid;
4037 catch (Exception ex)
4039 ex.Data["Instance"] = "ListTab(ShowGrid)";
4040 ex.Data["IsTerminatePermission"] = false;
4044 PlaySoundMenuItem.Checked = SettingDialog.PlaySound;
4045 this.PlaySoundFileMenuItem.Checked = SettingDialog.PlaySound;
4046 _fntUnread = SettingDialog.FontUnread;
4047 _clUnread = SettingDialog.ColorUnread;
4048 _fntReaded = SettingDialog.FontReaded;
4049 _clReaded = SettingDialog.ColorReaded;
4050 _clFav = SettingDialog.ColorFav;
4051 _clOWL = SettingDialog.ColorOWL;
4052 _clRetweet = SettingDialog.ColorRetweet;
4053 _fntDetail = SettingDialog.FontDetail;
4054 _clDetail = SettingDialog.ColorDetail;
4055 _clDetailLink = SettingDialog.ColorDetailLink;
4056 _clDetailBackcolor = SettingDialog.ColorDetailBackcolor;
4057 _clSelf = SettingDialog.ColorSelf;
4058 _clAtSelf = SettingDialog.ColorAtSelf;
4059 _clTarget = SettingDialog.ColorTarget;
4060 _clAtTarget = SettingDialog.ColorAtTarget;
4061 _clAtFromTarget = SettingDialog.ColorAtFromTarget;
4062 _clAtTo = SettingDialog.ColorAtTo;
4063 _clListBackcolor = SettingDialog.ColorListBackcolor;
4064 _clInputBackcolor = SettingDialog.ColorInputBackcolor;
4065 _clInputFont = SettingDialog.ColorInputFont;
4066 _fntInputFont = SettingDialog.FontInputFont;
4069 if (StatusText.Focused) StatusText.BackColor = _clInputBackcolor;
4070 StatusText.Font = _fntInputFont;
4071 StatusText.ForeColor = _clInputFont;
4073 catch (Exception ex)
4075 MessageBox.Show(ex.Message);
4078 _brsForeColorUnread.Dispose();
4079 _brsForeColorReaded.Dispose();
4080 _brsForeColorFav.Dispose();
4081 _brsForeColorOWL.Dispose();
4082 _brsForeColorRetweet.Dispose();
4083 _brsForeColorUnread = new SolidBrush(_clUnread);
4084 _brsForeColorReaded = new SolidBrush(_clReaded);
4085 _brsForeColorFav = new SolidBrush(_clFav);
4086 _brsForeColorOWL = new SolidBrush(_clOWL);
4087 _brsForeColorRetweet = new SolidBrush(_clRetweet);
4088 _brsBackColorMine.Dispose();
4089 _brsBackColorAt.Dispose();
4090 _brsBackColorYou.Dispose();
4091 _brsBackColorAtYou.Dispose();
4092 _brsBackColorAtFromTarget.Dispose();
4093 _brsBackColorAtTo.Dispose();
4094 _brsBackColorNone.Dispose();
4095 _brsBackColorMine = new SolidBrush(_clSelf);
4096 _brsBackColorAt = new SolidBrush(_clAtSelf);
4097 _brsBackColorYou = new SolidBrush(_clTarget);
4098 _brsBackColorAtYou = new SolidBrush(_clAtTarget);
4099 _brsBackColorAtFromTarget = new SolidBrush(_clAtFromTarget);
4100 _brsBackColorAtTo = new SolidBrush(_clAtTo);
4101 _brsBackColorNone = new SolidBrush(_clListBackcolor);
4104 if (SettingDialog.IsMonospace)
4106 detailHtmlFormatHeader = detailHtmlFormatMono1;
4107 detailHtmlFormatFooter = detailHtmlFormatMono7;
4111 detailHtmlFormatHeader = detailHtmlFormat1;
4112 detailHtmlFormatFooter = detailHtmlFormat7;
4114 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();
4115 if (SettingDialog.IsMonospace)
4117 detailHtmlFormatHeader += detailHtmlFormatMono6;
4121 detailHtmlFormatHeader += detailHtmlFormat6;
4124 catch (Exception ex)
4126 ex.Data["Instance"] = "Font";
4127 ex.Data["IsTerminatePermission"] = false;
4132 _statuses.SetUnreadManage(SettingDialog.UnreadManage);
4134 catch (Exception ex)
4136 ex.Data["Instance"] = "_statuses";
4137 ex.Data["IsTerminatePermission"] = false;
4143 foreach (TabPage tb in ListTab.TabPages)
4145 if (SettingDialog.TabIconDisp)
4147 if (_statuses.Tabs[tb.Text].UnreadCount == 0)
4152 if (tb.Tag != null && tb.Controls.Count > 0)
4154 ((DetailsListView)tb.Tag).Font = _fntReaded;
4155 ((DetailsListView)tb.Tag).BackColor = _clListBackcolor;
4159 catch (Exception ex)
4161 ex.Data["Instance"] = "ListTab(TabIconDisp no2)";
4162 ex.Data["IsTerminatePermission"] = false;
4165 SetMainWindowTitle();
4166 SetNotifyIconText();
4170 if (_curList != null) _curList.Refresh();
4173 Outputz.Key = SettingDialog.OutputzKey;
4174 Outputz.Enabled = SettingDialog.OutputzEnabled;
4175 switch (SettingDialog.OutputzUrlmode)
4177 case MyCommon.OutputzUrlmode.twittercom:
4178 Outputz.OutUrl = "http://twitter.com/";
4180 case MyCommon.OutputzUrlmode.twittercomWithUsername:
4181 Outputz.OutUrl = "http://twitter.com/" + tw.Username;
4185 _hookGlobalHotkey.UnregisterAllOriginalHotkey();
4186 if (SettingDialog.HotkeyEnabled)
4188 ///グローバルホットキーの登録。設定で変更可能にするかも
4189 HookGlobalHotkey.ModKeys modKey = HookGlobalHotkey.ModKeys.None;
4190 if ((SettingDialog.HotkeyMod & Keys.Alt) == Keys.Alt) modKey = modKey | HookGlobalHotkey.ModKeys.Alt;
4191 if ((SettingDialog.HotkeyMod & Keys.Control) == Keys.Control) modKey = modKey | HookGlobalHotkey.ModKeys.Ctrl;
4192 if ((SettingDialog.HotkeyMod & Keys.Shift) == Keys.Shift) modKey = modKey | HookGlobalHotkey.ModKeys.Shift;
4193 if ((SettingDialog.HotkeyMod & Keys.LWin) == Keys.LWin) modKey = modKey | HookGlobalHotkey.ModKeys.Win;
4195 _hookGlobalHotkey.RegisterOriginalHotkey(SettingDialog.HotkeyKey, SettingDialog.HotkeyValue, modKey);
4198 if (uid != tw.Username) this.doGetFollowersMenu();
4200 SetImageServiceCombo();
4201 if (SettingDialog.IsNotifyUseGrowl) gh.RegisterGrowl();
4204 StatusText_TextChanged(null, null);
4212 Twitter.AccountState = MyCommon.ACCOUNT_STATE.Valid;
4214 this.TopMost = SettingDialog.AlwaysTop;
4215 SaveConfigsAll(false);
4218 private void PostBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
4220 if (e.Url.AbsoluteUri != "about:blank")
4223 OpenUriAsync(e.Url.OriginalString);
4227 private void PostBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
4229 if (e.Url.Scheme == "data")
4231 StatusLabelUrl.Text = PostBrowser.StatusText.Replace("&", "&&");
4233 else if (e.Url.AbsoluteUri != "about:blank")
4237 if (e.Url.AbsoluteUri.StartsWith("http://twitter.com/search?q=%23") ||
4238 e.Url.AbsoluteUri.StartsWith("https://twitter.com/search?q=%23"))
4241 string urlStr = HttpUtility.UrlDecode(e.Url.AbsoluteUri);
4242 int i = urlStr.IndexOf('#');
4243 if (i == -1) return;
4245 string hash = urlStr.Substring(i);
4246 HashSupl.AddItem(hash);
4247 HashMgr.AddHashToHistory(hash.Trim(), false);
4248 AddNewTabForSearch(hash);
4253 Match m = Regex.Match(e.Url.AbsoluteUri, "^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)$");
4254 if (m.Success && IsTwitterId(m.Result("${ScreenName}")))
4256 // Ctrlを押しながらリンクをクリックした場合は設定と逆の動作をする
4257 if (SettingDialog.OpenUserTimeline)
4259 if (MyCommon.IsKeyDown(Keys.Control))
4260 OpenUriAsync(e.Url.OriginalString);
4262 this.AddNewTabForUserTimeline(m.Result("${ScreenName}"));
4266 if (MyCommon.IsKeyDown(Keys.Control))
4267 this.AddNewTabForUserTimeline(m.Result("${ScreenName}"));
4269 OpenUriAsync(e.Url.OriginalString);
4274 OpenUriAsync(e.Url.OriginalString);
4280 public void AddNewTabForSearch(string searchWord)
4282 //同一検索条件のタブが既に存在すれば、そのタブアクティブにして終了
4283 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.PublicSearch))
4285 if (tb.SearchWords == searchWord && string.IsNullOrEmpty(tb.SearchLang))
4287 foreach (TabPage tp in ListTab.TabPages)
4289 if (tb.TabName == tp.Text)
4291 ListTab.SelectedTab = tp;
4298 string tabName = searchWord;
4299 for (int i = 0; i <= 100; i++)
4301 if (_statuses.ContainsTab(tabName))
4307 _statuses.AddTab(tabName, MyCommon.TabUsageType.PublicSearch, null);
4308 AddNewTab(tabName, false, MyCommon.TabUsageType.PublicSearch);
4310 ListTab.SelectedIndex = ListTab.TabPages.Count - 1;
4312 ComboBox cmb = (ComboBox)ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"];
4313 cmb.Items.Add(searchWord);
4314 cmb.Text = searchWord;
4317 this.SearchButton_Click(ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"], null);
4320 private void ShowUserTimeline()
4322 if (!this.ExistCurrentPost) return;
4323 AddNewTabForUserTimeline(_curPost.ScreenName);
4326 private void SearchComboBox_KeyDown(object sender, KeyEventArgs e)
4328 if (e.KeyCode == Keys.Escape)
4330 TabPage relTp = ListTab.SelectedTab;
4331 RemoveSpecifiedTab(relTp.Text, false);
4333 e.SuppressKeyPress = true;
4337 public void AddNewTabForUserTimeline(string user)
4339 //同一検索条件のタブが既に存在すれば、そのタブアクティブにして終了
4340 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.UserTimeline))
4342 if (tb.User == user)
4344 foreach (TabPage tp in ListTab.TabPages)
4346 if (tb.TabName == tp.Text)
4348 ListTab.SelectedTab = tp;
4355 string tabName = "user:" + user;
4356 while (_statuses.ContainsTab(tabName))
4361 _statuses.AddTab(tabName, MyCommon.TabUsageType.UserTimeline, null);
4362 _statuses.Tabs[tabName].User = user;
4363 AddNewTab(tabName, false, MyCommon.TabUsageType.UserTimeline);
4365 ListTab.SelectedIndex = ListTab.TabPages.Count - 1;
4369 GetTimeline(MyCommon.WORKERTYPE.UserTimeline, 1, 0, tabName);
4372 public bool AddNewTab(string tabName, bool startup, MyCommon.TabUsageType tabType, ListElement listInfo = null)
4375 foreach (TabPage tb in ListTab.TabPages)
4377 if (tb.Text == tabName) return false;
4381 if (tabName == Properties.Resources.AddNewTabText1) return false;
4386 if (tabType == MyCommon.TabUsageType.DirectMessage ||
4387 tabType == MyCommon.TabUsageType.Favorites ||
4388 tabType == MyCommon.TabUsageType.Home ||
4389 tabType == MyCommon.TabUsageType.Mentions ||
4390 tabType == MyCommon.TabUsageType.Related)
4392 if (_statuses.GetTabByType(tabType) != null) return false;
4396 TabPage _tabPage = new TabPage();
4397 DetailsListView _listCustom = new DetailsListView();
4398 ColumnHeader _colHd1 = new ColumnHeader(); //アイコン
4399 ColumnHeader _colHd2 = new ColumnHeader(); //ニックネーム
4400 ColumnHeader _colHd3 = new ColumnHeader(); //本文
4401 ColumnHeader _colHd4 = new ColumnHeader(); //日付
4402 ColumnHeader _colHd5 = new ColumnHeader(); //ユーザID
4403 ColumnHeader _colHd6 = new ColumnHeader(); //未読
4404 ColumnHeader _colHd7 = new ColumnHeader(); //マーク&プロテクト
4405 ColumnHeader _colHd8 = new ColumnHeader(); //ソース
4407 int cnt = ListTab.TabPages.Count;
4409 ///ToDo:Create and set controls follow tabtypes
4411 this.SplitContainer1.Panel1.SuspendLayout();
4412 this.SplitContainer1.Panel2.SuspendLayout();
4413 this.SplitContainer1.SuspendLayout();
4414 this.ListTab.SuspendLayout();
4415 this.SuspendLayout();
4417 _tabPage.SuspendLayout();
4421 if (tabType == MyCommon.TabUsageType.UserTimeline || tabType == MyCommon.TabUsageType.Lists)
4423 label = new Label();
4424 label.Dock = DockStyle.Top;
4425 label.Name = "labelUser";
4426 if (tabType == MyCommon.TabUsageType.Lists)
4428 label.Text = listInfo.ToString();
4432 label.Text = _statuses.Tabs[tabName].User + "'s Timeline";
4434 label.TextAlign = ContentAlignment.MiddleLeft;
4435 using (ComboBox tmpComboBox = new ComboBox())
4437 label.Height = tmpComboBox.Height;
4439 _tabPage.Controls.Add(label);
4444 if (tabType == MyCommon.TabUsageType.PublicSearch)
4448 Label lbl = new Label();
4449 ComboBox cmb = new ComboBox();
4450 Button btn = new Button();
4451 ComboBox cmbLang = new ComboBox();
4453 pnl.SuspendLayout();
4455 pnl.Controls.Add(cmb);
4456 pnl.Controls.Add(cmbLang);
4457 pnl.Controls.Add(btn);
4458 pnl.Controls.Add(lbl);
4459 pnl.Name = "panelSearch";
4460 pnl.Dock = DockStyle.Top;
4461 pnl.Height = cmb.Height;
4462 pnl.Enter += SearchControls_Enter;
4463 pnl.Leave += SearchControls_Leave;
4466 cmb.Anchor = AnchorStyles.Left | AnchorStyles.Right;
4467 cmb.Dock = DockStyle.Fill;
4468 cmb.Name = "comboSearch";
4469 cmb.DropDownStyle = ComboBoxStyle.DropDown;
4470 cmb.ImeMode = ImeMode.NoControl;
4471 cmb.TabStop = false;
4472 cmb.AutoCompleteMode = AutoCompleteMode.None;
4473 cmb.KeyDown += SearchComboBox_KeyDown;
4475 if (_statuses.ContainsTab(tabName))
4477 cmb.Items.Add(_statuses.Tabs[tabName].SearchWords);
4478 cmb.Text = _statuses.Tabs[tabName].SearchWords;
4482 cmbLang.Anchor = AnchorStyles.Left | AnchorStyles.Right;
4483 cmbLang.Dock = DockStyle.Right;
4485 cmbLang.Name = "comboLang";
4486 cmbLang.DropDownStyle = ComboBoxStyle.DropDownList;
4487 cmbLang.TabStop = false;
4488 cmbLang.Items.Add("");
4489 cmbLang.Items.Add("ja");
4490 cmbLang.Items.Add("en");
4491 cmbLang.Items.Add("ar");
4492 cmbLang.Items.Add("da");
4493 cmbLang.Items.Add("nl");
4494 cmbLang.Items.Add("fa");
4495 cmbLang.Items.Add("fi");
4496 cmbLang.Items.Add("fr");
4497 cmbLang.Items.Add("de");
4498 cmbLang.Items.Add("hu");
4499 cmbLang.Items.Add("is");
4500 cmbLang.Items.Add("it");
4501 cmbLang.Items.Add("no");
4502 cmbLang.Items.Add("pl");
4503 cmbLang.Items.Add("pt");
4504 cmbLang.Items.Add("ru");
4505 cmbLang.Items.Add("es");
4506 cmbLang.Items.Add("sv");
4507 cmbLang.Items.Add("th");
4508 if (_statuses.ContainsTab(tabName)) cmbLang.Text = _statuses.Tabs[tabName].SearchLang;
4510 lbl.Text = "Search(C-S-f)";
4511 lbl.Name = "label1";
4512 lbl.Dock = DockStyle.Left;
4514 lbl.Height = cmb.Height;
4515 lbl.TextAlign = ContentAlignment.MiddleLeft;
4517 btn.Text = "Search";
4518 btn.Name = "buttonSearch";
4519 btn.UseVisualStyleBackColor = true;
4520 btn.Dock = DockStyle.Right;
4521 btn.TabStop = false;
4522 btn.Click += SearchButton_Click;
4525 this.ListTab.Controls.Add(_tabPage);
4526 _tabPage.Controls.Add(_listCustom);
4528 if (tabType == MyCommon.TabUsageType.PublicSearch) _tabPage.Controls.Add(pnl);
4529 if (tabType == MyCommon.TabUsageType.UserTimeline || tabType == MyCommon.TabUsageType.Lists) _tabPage.Controls.Add(label);
4531 _tabPage.Location = new Point(4, 4);
4532 _tabPage.Name = "CTab" + cnt.ToString();
4533 _tabPage.Size = new Size(380, 260);
4534 _tabPage.TabIndex = 2 + cnt;
4535 _tabPage.Text = tabName;
4536 _tabPage.UseVisualStyleBackColor = true;
4538 _listCustom.AllowColumnReorder = true;
4541 _listCustom.Columns.AddRange(new ColumnHeader[] {_colHd1, _colHd2, _colHd3, _colHd4, _colHd5, _colHd6, _colHd7, _colHd8});
4545 _listCustom.Columns.AddRange(new ColumnHeader[] {_colHd1, _colHd3});
4547 _listCustom.ContextMenuStrip = this.ContextMenuOperate;
4548 _listCustom.Dock = DockStyle.Fill;
4549 _listCustom.FullRowSelect = true;
4550 _listCustom.HideSelection = false;
4551 _listCustom.Location = new Point(0, 0);
4552 _listCustom.Margin = new Padding(0);
4553 _listCustom.Name = "CList" + Environment.TickCount.ToString();
4554 _listCustom.ShowItemToolTips = true;
4555 _listCustom.Size = new Size(380, 260);
4556 _listCustom.UseCompatibleStateImageBehavior = false;
4557 _listCustom.View = View.Details;
4558 _listCustom.OwnerDraw = true;
4559 _listCustom.VirtualMode = true;
4560 _listCustom.Font = _fntReaded;
4561 _listCustom.BackColor = _clListBackcolor;
4563 _listCustom.GridLines = SettingDialog.ShowGrid;
4564 _listCustom.AllowDrop = true;
4566 _listCustom.SelectedIndexChanged += MyList_SelectedIndexChanged;
4567 _listCustom.MouseDoubleClick += MyList_MouseDoubleClick;
4568 _listCustom.ColumnClick += MyList_ColumnClick;
4569 _listCustom.DrawColumnHeader += MyList_DrawColumnHeader;
4570 _listCustom.DragDrop += TweenMain_DragDrop;
4571 _listCustom.DragOver += TweenMain_DragOver;
4572 _listCustom.DrawItem += MyList_DrawItem;
4573 _listCustom.MouseClick += MyList_MouseClick;
4574 _listCustom.ColumnReordered += MyList_ColumnReordered;
4575 _listCustom.ColumnWidthChanged += MyList_ColumnWidthChanged;
4576 _listCustom.CacheVirtualItems += MyList_CacheVirtualItems;
4577 _listCustom.RetrieveVirtualItem += MyList_RetrieveVirtualItem;
4578 _listCustom.DrawSubItem += MyList_DrawSubItem;
4579 _listCustom.HScrolled += MyList_HScrolled;
4582 _colHd1.Text = ColumnText[0];
4584 _colHd2.Text = ColumnText[1];
4586 _colHd3.Text = ColumnText[2];
4587 _colHd3.Width = 300;
4588 _colHd4.Text = ColumnText[3];
4590 _colHd5.Text = ColumnText[4];
4592 _colHd6.Text = ColumnText[5];
4594 _colHd7.Text = ColumnText[6];
4596 _colHd8.Text = ColumnText[7];
4599 _listCustom.SmallImageList = new ImageList();
4602 _listCustom.SmallImageList.ImageSize = new Size(_iconSz, _iconSz);
4606 _listCustom.SmallImageList.ImageSize = new Size(1, 1);
4609 int[] dispOrder = new int[8];
4612 for (int i = 0; i < _curList.Columns.Count; i++)
4614 for (int j = 0; j < _curList.Columns.Count; j++)
4616 if (_curList.Columns[j].DisplayIndex == i)
4623 for (int i = 0; i < _curList.Columns.Count; i++)
4625 _listCustom.Columns[i].Width = _curList.Columns[i].Width;
4626 _listCustom.Columns[dispOrder[i]].DisplayIndex = i;
4633 _listCustom.Columns[0].Width = _cfgLocal.Width1;
4634 _listCustom.Columns[1].Width = _cfgLocal.Width3;
4635 _listCustom.Columns[0].DisplayIndex = 0;
4636 _listCustom.Columns[1].DisplayIndex = 1;
4640 for (int i = 0; i <= 7; i++)
4642 if (_cfgLocal.DisplayIndex1 == i)
4644 else if (_cfgLocal.DisplayIndex2 == i)
4646 else if (_cfgLocal.DisplayIndex3 == i)
4648 else if (_cfgLocal.DisplayIndex4 == i)
4650 else if (_cfgLocal.DisplayIndex5 == i)
4652 else if (_cfgLocal.DisplayIndex6 == i)
4654 else if (_cfgLocal.DisplayIndex7 == i)
4656 else if (_cfgLocal.DisplayIndex8 == i)
4659 _listCustom.Columns[0].Width = _cfgLocal.Width1;
4660 _listCustom.Columns[1].Width = _cfgLocal.Width2;
4661 _listCustom.Columns[2].Width = _cfgLocal.Width3;
4662 _listCustom.Columns[3].Width = _cfgLocal.Width4;
4663 _listCustom.Columns[4].Width = _cfgLocal.Width5;
4664 _listCustom.Columns[5].Width = _cfgLocal.Width6;
4665 _listCustom.Columns[6].Width = _cfgLocal.Width7;
4666 _listCustom.Columns[7].Width = _cfgLocal.Width8;
4667 for (int i = 0; i <= 7; i++)
4669 _listCustom.Columns[dispOrder[i]].DisplayIndex = i;
4674 if (tabType == MyCommon.TabUsageType.PublicSearch) pnl.ResumeLayout(false);
4676 _tabPage.ResumeLayout(false);
4678 this.SplitContainer1.Panel1.ResumeLayout(false);
4679 this.SplitContainer1.Panel2.ResumeLayout(false);
4680 this.SplitContainer1.ResumeLayout(false);
4681 this.ListTab.ResumeLayout(false);
4682 this.ResumeLayout(false);
4683 this.PerformLayout();
4684 _tabPage.Tag = _listCustom;
4688 public bool RemoveSpecifiedTab(string TabName, bool confirm)
4691 for (idx = 0; idx < ListTab.TabPages.Count; idx++)
4693 if (ListTab.TabPages[idx].Text == TabName) break;
4696 if (_statuses.IsDefaultTab(TabName) || _statuses.Tabs[TabName].Protected) return false;
4700 string tmp = string.Format(Properties.Resources.RemoveSpecifiedTabText1, Environment.NewLine);
4701 if (MessageBox.Show(tmp, TabName + " " + Properties.Resources.RemoveSpecifiedTabText2,
4702 MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Cancel)
4708 SetListProperty(); //他のタブに列幅等を反映
4710 MyCommon.TabUsageType tabType = _statuses.Tabs[TabName].TabType;
4713 this.SplitContainer1.Panel1.SuspendLayout();
4714 this.SplitContainer1.Panel2.SuspendLayout();
4715 this.SplitContainer1.SuspendLayout();
4716 this.ListTab.SuspendLayout();
4717 this.SuspendLayout();
4719 TabPage _tabPage = ListTab.TabPages[idx];
4720 DetailsListView _listCustom = (DetailsListView)_tabPage.Tag;
4721 _tabPage.Tag = null;
4723 _tabPage.SuspendLayout();
4725 if (this.ListTab.SelectedTab == this.ListTab.TabPages[idx])
4727 this.ListTab.SelectTab((this._beforeSelectedTab != null && this.ListTab.TabPages.Contains(this._beforeSelectedTab)) ? this._beforeSelectedTab : this.ListTab.TabPages[0]);
4729 this.ListTab.Controls.Remove(_tabPage);
4732 if (tabType == MyCommon.TabUsageType.PublicSearch)
4734 pnl = _tabPage.Controls["panelSearch"];
4735 foreach (Control ctrl in pnl.Controls)
4737 if (ctrl.Name == "buttonSearch")
4739 ctrl.Click -= SearchButton_Click;
4741 ctrl.Enter -= SearchControls_Enter;
4742 ctrl.Leave -= SearchControls_Leave;
4743 pnl.Controls.Remove(ctrl);
4746 _tabPage.Controls.Remove(pnl);
4749 _tabPage.Controls.Remove(_listCustom);
4750 _listCustom.Columns.Clear();
4751 _listCustom.ContextMenuStrip = null;
4753 _listCustom.SelectedIndexChanged -= MyList_SelectedIndexChanged;
4754 _listCustom.MouseDoubleClick -= MyList_MouseDoubleClick;
4755 _listCustom.ColumnClick -= MyList_ColumnClick;
4756 _listCustom.DrawColumnHeader -= MyList_DrawColumnHeader;
4757 _listCustom.DragDrop -= TweenMain_DragDrop;
4758 _listCustom.DragOver -= TweenMain_DragOver;
4759 _listCustom.DrawItem -= MyList_DrawItem;
4760 _listCustom.MouseClick -= MyList_MouseClick;
4761 _listCustom.ColumnReordered -= MyList_ColumnReordered;
4762 _listCustom.ColumnWidthChanged -= MyList_ColumnWidthChanged;
4763 _listCustom.CacheVirtualItems -= MyList_CacheVirtualItems;
4764 _listCustom.RetrieveVirtualItem -= MyList_RetrieveVirtualItem;
4765 _listCustom.DrawSubItem -= MyList_DrawSubItem;
4766 _listCustom.HScrolled -= MyList_HScrolled;
4768 _listCustom.SmallImageList = null;
4769 _listCustom.ListViewItemSorter = null;
4772 if (_curTab.Equals(_tabPage))
4780 _itemCacheIndex = -1;
4783 _tabPage.ResumeLayout(false);
4785 this.SplitContainer1.Panel1.ResumeLayout(false);
4786 this.SplitContainer1.Panel2.ResumeLayout(false);
4787 this.SplitContainer1.ResumeLayout(false);
4788 this.ListTab.ResumeLayout(false);
4789 this.ResumeLayout(false);
4790 this.PerformLayout();
4793 _listCustom.Dispose();
4794 _statuses.RemoveTab(TabName);
4796 foreach (TabPage tp in ListTab.TabPages)
4798 DetailsListView lst = (DetailsListView)tp.Tag;
4799 if (lst.VirtualListSize != _statuses.Tabs[tp.Text].AllCount)
4801 lst.VirtualListSize = _statuses.Tabs[tp.Text].AllCount;
4808 private void ListTab_Deselected(object sender, TabControlEventArgs e)
4811 _itemCacheIndex = -1;
4813 _beforeSelectedTab = e.TabPage;
4816 private void ListTab_MouseMove(object sender, MouseEventArgs e)
4820 if (!SettingDialog.TabMouseLock && e.Button == MouseButtons.Left && _tabDrag)
4823 Rectangle dragEnableRectangle = new Rectangle((int)(_tabMouseDownPoint.X - (SystemInformation.DragSize.Width / 2)), (int)(_tabMouseDownPoint.Y - (SystemInformation.DragSize.Height / 2)), SystemInformation.DragSize.Width, SystemInformation.DragSize.Height);
4824 if (!dragEnableRectangle.Contains(e.Location))
4826 //タブが多段の場合にはMouseDownの前の段階で選択されたタブの段が変わっているので、このタイミングでカーソルの位置からタブを判定出来ない。
4827 tn = ListTab.SelectedTab.Text;
4830 if (string.IsNullOrEmpty(tn)) return;
4832 foreach (TabPage tb in ListTab.TabPages)
4836 ListTab.DoDragDrop(tb, DragDropEffects.All);
4846 Point cpos = new Point(e.X, e.Y);
4847 for (int i = 0; i < ListTab.TabPages.Count; i++)
4849 Rectangle rect = ListTab.GetTabRect(i);
4850 if (rect.Left <= cpos.X & cpos.X <= rect.Right &
4851 rect.Top <= cpos.Y & cpos.Y <= rect.Bottom)
4853 _rclickTabName = ListTab.TabPages[i].Text;
4859 private void ListTab_SelectedIndexChanged(object sender, EventArgs e)
4861 //_curList.Refresh();
4863 SetMainWindowTitle();
4864 SetStatusLabelUrl();
4865 if (ListTab.Focused || ((Control)ListTab.SelectedTab.Tag).Focused) this.Tag = ListTab.Tag;
4866 TabMenuControl(ListTab.SelectedTab.Text);
4867 this.PushSelectPostChain();
4870 private void SetListProperty()
4872 //削除などで見つからない場合は処理せず
4873 if (_curList == null) return;
4874 if (!_isColumnChanged) return;
4876 int[] dispOrder = new int[_curList.Columns.Count];
4877 for (int i = 0; i < _curList.Columns.Count; i++)
4879 for (int j = 0; j < _curList.Columns.Count; j++)
4881 if (_curList.Columns[j].DisplayIndex == i)
4890 foreach (TabPage tb in ListTab.TabPages)
4892 if (!tb.Equals(_curTab))
4894 if (tb.Tag != null && tb.Controls.Count > 0)
4896 DetailsListView lst = (DetailsListView)tb.Tag;
4897 for (int i = 0; i < lst.Columns.Count; i++)
4899 lst.Columns[dispOrder[i]].DisplayIndex = i;
4900 lst.Columns[i].Width = _curList.Columns[i].Width;
4906 _isColumnChanged = false;
4909 private void PostBrowser_StatusTextChanged(object sender, EventArgs e)
4913 if (PostBrowser.StatusText.StartsWith("http") || PostBrowser.StatusText.StartsWith("ftp")
4914 || PostBrowser.StatusText.StartsWith("data"))
4916 StatusLabelUrl.Text = PostBrowser.StatusText.Replace("&", "&&");
4918 if (string.IsNullOrEmpty(PostBrowser.StatusText))
4920 SetStatusLabelUrl();
4928 private void StatusText_KeyPress(object sender, KeyPressEventArgs e)
4930 if (e.KeyChar == '@')
4932 if (!SettingDialog.UseAtIdSupplement) return;
4934 int cnt = AtIdSupl.ItemCount;
4935 ShowSuplDialog(StatusText, AtIdSupl);
4936 if (cnt != AtIdSupl.ItemCount) _modifySettingAtId = true;
4939 else if (e.KeyChar == '#')
4941 if (!SettingDialog.UseHashSupplement) return;
4942 ShowSuplDialog(StatusText, HashSupl);
4947 public void ShowSuplDialog(TextBox owner, AtIdSupplement dialog)
4949 ShowSuplDialog(owner, dialog, 0, "");
4952 public void ShowSuplDialog(TextBox owner, AtIdSupplement dialog, int offset)
4954 ShowSuplDialog(owner, dialog, offset, "");
4957 public void ShowSuplDialog(TextBox owner, AtIdSupplement dialog, int offset, string startswith)
4959 dialog.StartsWith = startswith;
4966 dialog.ShowDialog();
4968 this.TopMost = SettingDialog.AlwaysTop;
4969 int selStart = owner.SelectionStart;
4972 if (dialog.DialogResult == DialogResult.OK)
4974 if (!string.IsNullOrEmpty(dialog.inputText))
4978 fHalf = owner.Text.Substring(0, selStart - offset);
4980 if (selStart < owner.Text.Length)
4982 eHalf = owner.Text.Substring(selStart);
4984 owner.Text = fHalf + dialog.inputText + eHalf;
4985 owner.SelectionStart = selStart + dialog.inputText.Length;
4992 fHalf = owner.Text.Substring(0, selStart);
4994 if (selStart < owner.Text.Length)
4996 eHalf = owner.Text.Substring(selStart);
4998 owner.Text = fHalf + eHalf;
5001 owner.SelectionStart = selStart;
5007 private void StatusText_KeyUp(object sender, KeyEventArgs e)
5010 if (!e.Alt && !e.Control && !e.Shift)
5012 if (e.KeyCode == Keys.Space || e.KeyCode == Keys.ProcessKey)
5014 bool isSpace = false;
5015 foreach (char c in StatusText.Text.ToCharArray())
5017 if (c == ' ' || c == ' ')
5030 StatusText.Text = "";
5031 JumpUnreadMenuItem_Click(null, null);
5035 this.StatusText_TextChanged(null, null);
5038 private void StatusText_TextChanged(object sender, EventArgs e)
5041 int pLen = GetRestStatusCount(true, false);
5042 lblLen.Text = pLen.ToString();
5045 StatusText.ForeColor = Color.Red;
5049 StatusText.ForeColor = _clInputFont;
5051 if (string.IsNullOrEmpty(StatusText.Text))
5054 _reply_to_name = "";
5058 private int GetRestStatusCount(bool isAuto, bool isAddFooter)
5061 int pLen = 140 - StatusText.Text.Length;
5062 if (this.NotifyIcon1 == null || !this.NotifyIcon1.Visible) return pLen;
5063 if ((isAuto && !MyCommon.IsKeyDown(Keys.Control) && SettingDialog.PostShiftEnter) ||
5064 (isAuto && !MyCommon.IsKeyDown(Keys.Shift) && !SettingDialog.PostShiftEnter) ||
5065 (!isAuto && isAddFooter))
5067 if (SettingDialog.UseRecommendStatus)
5068 pLen -= SettingDialog.RecommendStatusText.Length;
5069 else if (SettingDialog.Status.Length > 0)
5070 pLen -= SettingDialog.Status.Length + 1;
5072 if (!string.IsNullOrEmpty(HashMgr.UseHash))
5074 pLen -= HashMgr.UseHash.Length + 1;
5076 //foreach (Match m in Regex.Matches(StatusText.Text, "https?:\/\/[-_.!~*//()a-zA-Z0-9;\/?:\@&=+\$,%#^]+"))
5078 // pLen += m.Length - SettingDialog.TwitterConfiguration.ShortUrlLength;
5080 foreach (Match m in Regex.Matches(StatusText.Text, Twitter.rgUrl, RegexOptions.IgnoreCase))
5082 string before = m.Result("${before}");
5083 string url = m.Result("${url}");
5084 string protocol = m.Result("${protocol}");
5085 string domain = m.Result("${domain}");
5086 string path = m.Result("${path}");
5087 if (protocol.Length == 0)
5089 if (Regex.IsMatch(before, Twitter.url_invalid_without_protocol_preceding_chars))
5094 bool last_url_invalid_match = false;
5095 string lasturl = null;
5096 foreach (Match mm in Regex.Matches(domain, Twitter.url_valid_ascii_domain, RegexOptions.IgnoreCase))
5098 lasturl = mm.ToString();
5099 last_url_invalid_match = Regex.IsMatch(lasturl, Twitter.url_invalid_short_domain, RegexOptions.IgnoreCase);
5100 if (!last_url_invalid_match)
5102 pLen += lasturl.Length - SettingDialog.TwitterConfiguration.ShortUrlLength;
5106 if (path.Length != 0)
5108 if (last_url_invalid_match)
5110 pLen += lasturl.Length - SettingDialog.TwitterConfiguration.ShortUrlLength;
5112 pLen += path.Length;
5117 pLen += url.Length - SettingDialog.TwitterConfiguration.ShortUrlLength;
5120 //if (m.Result("${url}").Length > SettingDialog.TwitterConfiguration.ShortUrlLength)
5122 // pLen += m.Result("${url}").Length - SettingDialog.TwitterConfiguration.ShortUrlLength;
5125 if (ImageSelectionPanel.Visible && ImageSelectedPicture.Tag != null && !string.IsNullOrEmpty(this.ImageService))
5127 pLen -= SettingDialog.TwitterConfiguration.CharactersReservedPerMedia;
5132 private void MyList_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e)
5134 if (_itemCache != null &&
5135 e.StartIndex >= _itemCacheIndex &&
5136 e.EndIndex < _itemCacheIndex + _itemCache.Length &&
5137 _curList.Equals(sender))
5139 //If the newly requested cache is a subset of the old cache,
5140 //no need to rebuild everything, so do nothing.
5144 //Now we need to rebuild the cache.
5145 if (_curList.Equals(sender)) CreateCache(e.StartIndex, e.EndIndex);
5148 private void MyList_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
5150 if (_itemCache != null && e.ItemIndex >= _itemCacheIndex && e.ItemIndex < _itemCacheIndex + _itemCache.Length && _curList.Equals(sender))
5152 //A cache hit, so get the ListViewItem from the cache instead of making a new one.
5153 e.Item = _itemCache[e.ItemIndex - _itemCacheIndex];
5157 //A cache miss, so create a new ListViewItem and pass it back.
5158 TabPage tb = (TabPage)((DetailsListView)sender).Parent;
5161 e.Item = CreateItem(tb,
5162 _statuses[tb.Text, e.ItemIndex],
5168 string[] sitem = {"", "", "", "", "", "", "", ""};
5169 e.Item = new ImageListViewItem(sitem, "");
5174 private void CreateCache(int StartIndex, int EndIndex)
5178 //キャッシュ要求(要求範囲±30を作成)
5180 if (StartIndex < 0) StartIndex = 0;
5182 if (EndIndex >= _statuses.Tabs[_curTab.Text].AllCount) EndIndex = _statuses.Tabs[_curTab.Text].AllCount - 1;
5183 _postCache = _statuses[_curTab.Text, StartIndex, EndIndex]; //配列で取得
5184 _itemCacheIndex = StartIndex;
5186 _itemCache = new ListViewItem[0] {};
5187 Array.Resize(ref _itemCache, _postCache.Length);
5189 for (int i = 0; i < _postCache.Length; i++)
5191 _itemCache[i] = CreateItem(_curTab, _postCache[i], StartIndex + i);
5196 //キャッシュ要求が実データとずれるため(イベントの遅延?)
5202 private ListViewItem CreateItem(TabPage Tab, PostClass Post, int Index)
5204 StringBuilder mk = new StringBuilder();
5205 //if (Post.IsDeleted) mk.Append("×");
5206 //if (Post.IsMark) mk.Append("♪");
5207 //if (Post.IsProtect) mk.Append("Ю");
5208 //if (Post.InReplyToStatusId > 0) mk.Append("⇒");
5209 if (Post.FavoritedCount > 0) mk.Append("+" + Post.FavoritedCount.ToString());
5210 ImageListViewItem itm;
5211 if (Post.RetweetedId == 0)
5213 string[] sitem= {"",
5215 Post.IsDeleted ? "(DELETED)" : Post.TextSingleLine,
5216 Post.CreatedAt.ToString(SettingDialog.DateTimeFormat),
5221 itm = new ImageListViewItem(sitem, (ImageDictionary)this.TIconDic, Post.ImageUrl);
5225 string[] sitem = {"",
5227 Post.IsDeleted ? "(DELETED)" : Post.TextSingleLine,
5228 Post.CreatedAt.ToString(SettingDialog.DateTimeFormat),
5229 Post.ScreenName + Environment.NewLine + "(RT:" + Post.RetweetedBy + ")",
5233 itm = new ImageListViewItem(sitem, (ImageDictionary)this.TIconDic, Post.ImageUrl);
5235 itm.StateImageIndex = Post.StateIndex;
5237 bool read = Post.IsRead;
5238 //未読管理していなかったら既読として扱う
5239 if (!_statuses.Tabs[Tab.Text].UnreadManage || !SettingDialog.UnreadManage) read = true;
5240 ChangeItemStyleRead(read, itm, Post, null);
5241 if (Tab.Equals(_curTab)) ColorizeList(itm, Index);
5245 private void MyList_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
5247 e.DrawDefault = true;
5250 private void MyList_HScrolled(object sender, EventArgs e)
5252 DetailsListView listView = (DetailsListView)sender;
5256 private void MyList_DrawItem(object sender, DrawListViewItemEventArgs e)
5258 if (e.State == 0) return;
5259 e.DrawDefault = false;
5260 if (!e.Item.Selected) //e.ItemStateでうまく判定できない???
5262 SolidBrush brs2 = null;
5264 if (e.Item.BackColor == _clSelf)
5265 brs2 = _brsBackColorMine;
5266 else if (e.Item.BackColor == _clAtSelf)
5267 brs2 = _brsBackColorAt;
5268 else if (e.Item.BackColor == _clTarget)
5269 brs2 = _brsBackColorYou;
5270 else if (e.Item.BackColor == _clAtTarget)
5271 brs2 = _brsBackColorAtYou;
5272 else if (e.Item.BackColor == _clAtFromTarget)
5273 brs2 = _brsBackColorAtFromTarget;
5274 else if (e.Item.BackColor == _clAtTo)
5275 brs2 = _brsBackColorAtTo;
5277 brs2 = _brsBackColorNone;
5279 e.Graphics.FillRectangle(brs2, e.Bounds);
5284 if (((Control)sender).Focused)
5285 e.Graphics.FillRectangle(_brsHighLight, e.Bounds);
5287 e.Graphics.FillRectangle(_brsDeactiveSelection, e.Bounds);
5289 if ((e.State & ListViewItemStates.Focused) == ListViewItemStates.Focused) e.DrawFocusRectangle();
5290 this.DrawListViewItemIcon(e);
5293 private void MyList_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
5295 if (e.ItemState == 0) return;
5297 if (e.ColumnIndex > 0)
5300 RectangleF rct = e.Bounds;
5301 RectangleF rctB = e.Bounds;
5302 rct.Width = e.Header.Width;
5303 rctB.Width = e.Header.Width;
5306 rct.Y += e.Item.Font.Height;
5307 rct.Height -= e.Item.Font.Height;
5308 rctB.Height = e.Item.Font.Height;
5313 int drawLineCount = Math.Max(1, Math.DivRem((int)rct.Height, e.Item.Font.Height, out heightDiff));
5315 //if (heightDiff > e.Item.Font.Height * 0.7)
5317 // rct.Height += e.Item.Font.Height;
5318 // drawLineCount += 1;
5321 //フォントの高さの半分を足してるのは保険。無くてもいいかも。
5322 if (!_iconCol && drawLineCount <= 1)
5324 //rct.Inflate(0, heightDiff / -2);
5325 //rct.Height += e.Item.Font.Height / 2;
5327 else if (heightDiff < e.Item.Font.Height * 0.7)
5329 //最終行が70%以上欠けていたら、最終行は表示しない
5330 //rct.Height = (float)((e.Item.Font.Height * drawLineCount) + (e.Item.Font.Height / 2));
5331 rct.Height = (e.Item.Font.Height * drawLineCount) - 1;
5338 //if (!_iconCol && drawLineCount > 1)
5340 // rct.Y += e.Item.Font.Height * 0.2;
5341 // if (heightDiff >= e.Item.Font.Height * 0.8) rct.Height -= e.Item.Font.Height * 0.2;
5343 if (!e.Item.Selected) //e.ItemStateでうまく判定できない???
5347 SolidBrush brs = null;
5350 if (e.Item.ForeColor == _clUnread)
5352 brs = _brsForeColorUnread;
5354 else if (e.Item.ForeColor == _clReaded)
5356 brs = _brsForeColorReaded;
5358 else if (e.Item.ForeColor == _clFav)
5360 brs = _brsForeColorFav;
5362 else if (e.Item.ForeColor == _clOWL)
5364 brs = _brsForeColorOWL;
5366 else if (e.Item.ForeColor == _clRetweet)
5368 brs = _brsForeColorRetweet;
5372 brs = new SolidBrush(e.Item.ForeColor);
5380 using (Font fnt = new Font(e.Item.Font, FontStyle.Bold))
5382 //e.Graphics.DrawString(System.Environment.NewLine + e.Item.SubItems[2].Text, e.Item.Font, brs, rct, sf);
5383 //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);
5384 TextRenderer.DrawText(e.Graphics,
5385 e.Item.SubItems[2].Text,
5387 Rectangle.Round(rct),
5389 TextFormatFlags.WordBreak |
5390 TextFormatFlags.EndEllipsis |
5391 TextFormatFlags.GlyphOverhangPadding |
5392 TextFormatFlags.NoPrefix);
5393 TextRenderer.DrawText(e.Graphics,
5394 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 + "]",
5396 Rectangle.Round(rctB),
5398 TextFormatFlags.SingleLine |
5399 TextFormatFlags.EndEllipsis |
5400 TextFormatFlags.GlyphOverhangPadding |
5401 TextFormatFlags.NoPrefix);
5404 else if (drawLineCount == 1)
5406 TextRenderer.DrawText(e.Graphics,
5409 Rectangle.Round(rct),
5411 TextFormatFlags.SingleLine |
5412 TextFormatFlags.EndEllipsis |
5413 TextFormatFlags.GlyphOverhangPadding |
5414 TextFormatFlags.NoPrefix |
5415 TextFormatFlags.VerticalCenter);
5419 //e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, brs, rct, sf);
5420 TextRenderer.DrawText(e.Graphics,
5423 Rectangle.Round(rct),
5425 TextFormatFlags.WordBreak |
5426 TextFormatFlags.EndEllipsis |
5427 TextFormatFlags.GlyphOverhangPadding |
5428 TextFormatFlags.NoPrefix);
5431 if (flg) brs.Dispose();
5438 using (Font fnt = new Font(e.Item.Font, FontStyle.Bold))
5440 if (((Control)sender).Focused)
5444 //e.Graphics.DrawString(System.Environment.NewLine + e.Item.SubItems[2].Text, e.Item.Font, _brsHighLightText, rct, sf);
5445 //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);
5446 TextRenderer.DrawText(e.Graphics,
5447 e.Item.SubItems[2].Text,
5449 Rectangle.Round(rct),
5450 _brsHighLightText.Color,
5451 TextFormatFlags.WordBreak |
5452 TextFormatFlags.EndEllipsis |
5453 TextFormatFlags.GlyphOverhangPadding |
5454 TextFormatFlags.NoPrefix);
5455 TextRenderer.DrawText(e.Graphics,
5456 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 + "]",
5458 Rectangle.Round(rctB),
5459 _brsHighLightText.Color,
5460 TextFormatFlags.SingleLine |
5461 TextFormatFlags.EndEllipsis |
5462 TextFormatFlags.GlyphOverhangPadding |
5463 TextFormatFlags.NoPrefix);
5465 else if (drawLineCount == 1)
5467 TextRenderer.DrawText(e.Graphics,
5470 Rectangle.Round(rct),
5471 _brsHighLightText.Color,
5472 TextFormatFlags.SingleLine |
5473 TextFormatFlags.EndEllipsis |
5474 TextFormatFlags.GlyphOverhangPadding |
5475 TextFormatFlags.NoPrefix |
5476 TextFormatFlags.VerticalCenter);
5480 //e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, _brsHighLightText, rct, sf);
5481 TextRenderer.DrawText(e.Graphics,
5484 Rectangle.Round(rct),
5485 _brsHighLightText.Color,
5486 TextFormatFlags.WordBreak |
5487 TextFormatFlags.EndEllipsis |
5488 TextFormatFlags.GlyphOverhangPadding |
5489 TextFormatFlags.NoPrefix);
5496 //e.Graphics.DrawString(System.Environment.NewLine + e.Item.SubItems[2].Text, e.Item.Font, _brsForeColorUnread, rct, sf);
5497 //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);
5498 TextRenderer.DrawText(e.Graphics,
5499 e.Item.SubItems[2].Text,
5501 Rectangle.Round(rct),
5502 _brsForeColorUnread.Color,
5503 TextFormatFlags.WordBreak |
5504 TextFormatFlags.EndEllipsis |
5505 TextFormatFlags.GlyphOverhangPadding |
5506 TextFormatFlags.NoPrefix);
5507 TextRenderer.DrawText(e.Graphics,
5508 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 + "]",
5510 Rectangle.Round(rctB),
5511 _brsForeColorUnread.Color,
5512 TextFormatFlags.SingleLine |
5513 TextFormatFlags.EndEllipsis |
5514 TextFormatFlags.GlyphOverhangPadding |
5515 TextFormatFlags.NoPrefix);
5517 else if (drawLineCount == 1)
5519 TextRenderer.DrawText(e.Graphics,
5522 Rectangle.Round(rct),
5523 _brsForeColorUnread.Color,
5524 TextFormatFlags.SingleLine |
5525 TextFormatFlags.EndEllipsis |
5526 TextFormatFlags.GlyphOverhangPadding |
5527 TextFormatFlags.NoPrefix |
5528 TextFormatFlags.VerticalCenter);
5532 //e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, _brsForeColorUnread, rct, sf);
5533 TextRenderer.DrawText(e.Graphics,
5536 Rectangle.Round(rct),
5537 _brsForeColorUnread.Color,
5538 TextFormatFlags.WordBreak |
5539 TextFormatFlags.EndEllipsis |
5540 TextFormatFlags.GlyphOverhangPadding |
5541 TextFormatFlags.NoPrefix);
5547 //if (e.ColumnIndex == 6) this.DrawListViewItemStateIcon(e, rct);
5551 private void DrawListViewItemIcon(DrawListViewItemEventArgs e)
5553 ImageListViewItem item = (ImageListViewItem)e.Item;
5554 Rectangle stateRect;
5556 //e.Bounds.Leftが常に0を指すから自前で計算
5557 Rectangle itemRect = item.Bounds;
5558 itemRect.Width = e.Item.ListView.Columns[0].Width;
5560 foreach (ColumnHeader clm in e.Item.ListView.Columns)
5562 if (clm.DisplayIndex < e.Item.ListView.Columns[0].DisplayIndex)
5563 itemRect.X += clm.Width;
5567 if (item.Image != null)
5569 iconRect = Rectangle.Intersect(new Rectangle(e.Item.GetBounds(ItemBoundsPortion.Icon).Location, new Size(_iconSz, _iconSz)), itemRect);
5570 iconRect.Offset(0, Math.Max(0, (itemRect.Height - _iconSz) / 2));
5571 stateRect = Rectangle.Intersect(new Rectangle(iconRect.Location.X + _iconSz + 2, iconRect.Location.Y, 18, 16), itemRect);
5575 iconRect = Rectangle.Intersect(new Rectangle(e.Item.GetBounds(ItemBoundsPortion.Icon).Location, new Size(1, 1)), itemRect);
5576 //iconRect.Offset(0, Math.Max(0, (itemRect.Height - _iconSz) / 2));
5577 stateRect = Rectangle.Intersect(new Rectangle(iconRect.Location.X + _iconSz + 2, iconRect.Location.Y, 18, 16), itemRect);
5580 if (item.Image != null && iconRect.Width > 0)
5582 e.Graphics.FillRectangle(Brushes.White, iconRect);
5583 e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
5586 e.Graphics.DrawImage(item.Image, iconRect);
5588 catch (ArgumentException)
5594 if (item.StateImageIndex > -1)
5596 if (stateRect.Width > 0)
5598 //e.Graphics.FillRectangle(Brushes.White, stateRect);
5599 //e.Graphics.InterpolationMode = Drawing2D.InterpolationMode.High;
5600 e.Graphics.DrawImage(this.PostStateImageList.Images[item.StateImageIndex], stateRect);
5605 //private void DrawListViewItemStateIcon(DrawListViewSubItemEventArgs e, RectangleF rct)
5607 // ImageListViewItem item = (ImageListViewItem)e.Item;
5608 // if (item.StateImageIndex > -1)
5610 // ////e.Bounds.Leftが常に0を指すから自前で計算
5611 // //Rectangle itemRect = item.Bounds;
5612 // //itemRect.Width = e.Item.ListView.Columns[4].Width;
5614 // //foreach (ColumnHeader clm in e.Item.ListView.Columns)
5616 // // if (clm.DisplayIndex < e.Item.ListView.Columns[4].DisplayIndex)
5618 // // itemRect.X += clm.Width;
5622 // //Rectangle iconRect = Rectangle.Intersect(new Rectangle(e.Item.GetBounds(ItemBoundsPortion.Icon).Location, new Size(_iconSz, _iconSz)), itemRect);
5623 // //iconRect.Offset(0, Math.Max(0, (itemRect.Height - _iconSz) / 2));
5625 // if (rct.Width > 0)
5627 // RectangleF stateRect = RectangleF.Intersect(rct, new RectangleF(rct.Location, new Size(18, 16)));
5628 // //e.Graphics.FillRectangle(Brushes.White, rct);
5629 // //e.Graphics.InterpolationMode = Drawing2D.InterpolationMode.High;
5630 // e.Graphics.DrawImage(this.PostStateImageList.Images(item.StateImageIndex), stateRect);
5635 private void DoTabSearch(string _word,
5645 if (_curList.VirtualListSize == 0)
5647 MessageBox.Show(Properties.Resources.DoTabSearchText2, Properties.Resources.DoTabSearchText3, MessageBoxButtons.OK, MessageBoxIcon.Information);
5650 if (_curList.SelectedIndices.Count > 0)
5652 cidx = _curList.SelectedIndices[0];
5654 toIdx = _curList.VirtualListSize;
5658 case SEARCHTYPE.DialogSearch: //ダイアログからの検索
5659 if (_curList.SelectedIndices.Count > 0)
5660 cidx = _curList.SelectedIndices[0];
5664 case SEARCHTYPE.NextSearch: //次を検索
5665 if (_curList.SelectedIndices.Count > 0)
5667 cidx = _curList.SelectedIndices[0] + 1;
5668 if (cidx > toIdx) cidx = toIdx;
5675 case SEARCHTYPE.PrevSearch: //前を検索
5676 if (_curList.SelectedIndices.Count > 0)
5678 cidx = _curList.SelectedIndices[0] - 1;
5679 if (cidx < 0) cidx = 0;
5690 RegexOptions regOpt = RegexOptions.None;
5691 StringComparison fndOpt = StringComparison.Ordinal;
5694 regOpt = RegexOptions.IgnoreCase;
5695 fndOpt = StringComparison.OrdinalIgnoreCase;
5706 _search = new Regex(_word, regOpt);
5707 for (int idx = cidx; idx != toIdx; idx += stp)
5712 post = _statuses[_curTab.Text, idx];
5718 if (_search.IsMatch(post.Nickname)
5719 || _search.IsMatch(post.TextFromApi)
5720 || _search.IsMatch(post.ScreenName))
5722 SelectListItem(_curList, idx);
5723 _curList.EnsureVisible(idx);
5728 catch (ArgumentException)
5730 MessageBox.Show(Properties.Resources.DoTabSearchText1, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
5737 for (int idx = cidx; idx != toIdx; idx += stp)
5742 post = _statuses[_curTab.Text, idx];
5748 if (post.Nickname.IndexOf(_word, fndOpt) > -1
5749 || post.TextFromApi.IndexOf(_word, fndOpt) > -1
5750 || post.ScreenName.IndexOf(_word, fndOpt) > -1)
5752 SelectListItem(_curList, idx);
5753 _curList.EnsureVisible(idx);
5763 case SEARCHTYPE.DialogSearch:
5764 case SEARCHTYPE.NextSearch:
5768 case SEARCHTYPE.PrevSearch:
5770 cidx = _curList.Items.Count - 1;
5777 catch (ArgumentOutOfRangeException)
5780 MessageBox.Show(Properties.Resources.DoTabSearchText2, Properties.Resources.DoTabSearchText3, MessageBoxButtons.OK, MessageBoxIcon.Information);
5783 private void MenuItemSubSearch_Click(object sender, EventArgs e)
5786 SearchDialog.Owner = this;
5787 if (SearchDialog.ShowDialog() == DialogResult.Cancel)
5789 this.TopMost = SettingDialog.AlwaysTop;
5792 this.TopMost = SettingDialog.AlwaysTop;
5794 if (!string.IsNullOrEmpty(SearchDialog.SWord))
5796 DoTabSearch(SearchDialog.SWord,
5797 SearchDialog.CheckCaseSensitive,
5798 SearchDialog.CheckRegex,
5799 SEARCHTYPE.DialogSearch);
5803 private void MenuItemSearchNext_Click(object sender, EventArgs e)
5806 if (string.IsNullOrEmpty(SearchDialog.SWord))
5808 if (SearchDialog.ShowDialog() == DialogResult.Cancel)
5810 this.TopMost = SettingDialog.AlwaysTop;
5813 this.TopMost = SettingDialog.AlwaysTop;
5814 if (string.IsNullOrEmpty(SearchDialog.SWord)) return;
5816 DoTabSearch(SearchDialog.SWord,
5817 SearchDialog.CheckCaseSensitive,
5818 SearchDialog.CheckRegex,
5819 SEARCHTYPE.DialogSearch);
5823 DoTabSearch(SearchDialog.SWord,
5824 SearchDialog.CheckCaseSensitive,
5825 SearchDialog.CheckRegex,
5826 SEARCHTYPE.NextSearch);
5830 private void MenuItemSearchPrev_Click(object sender, EventArgs e)
5833 if (string.IsNullOrEmpty(SearchDialog.SWord))
5835 if (SearchDialog.ShowDialog() == DialogResult.Cancel)
5837 this.TopMost = SettingDialog.AlwaysTop;
5840 this.TopMost = SettingDialog.AlwaysTop;
5841 if (string.IsNullOrEmpty(SearchDialog.SWord)) return;
5844 DoTabSearch(SearchDialog.SWord,
5845 SearchDialog.CheckCaseSensitive,
5846 SearchDialog.CheckRegex,
5847 SEARCHTYPE.PrevSearch);
5850 private void AboutMenuItem_Click(object sender, EventArgs e)
5852 using (TweenAboutBox about = new TweenAboutBox())
5854 about.ShowDialog(this);
5856 this.TopMost = SettingDialog.AlwaysTop;
5859 private void JumpUnreadMenuItem_Click(object sender, EventArgs e)
5861 int bgnIdx = ListTab.TabPages.IndexOf(_curTab);
5863 DetailsListView lst = null;
5865 if (ImageSelectionPanel.Enabled)
5869 for (int i = bgnIdx; i < ListTab.TabPages.Count; i++)
5872 idx = _statuses.GetOldestUnreadIndex(ListTab.TabPages[i].Text);
5875 ListTab.SelectedIndex = i;
5876 lst = (DetailsListView)ListTab.TabPages[i].Tag;
5877 //_curTab = ListTab.TabPages[i];
5882 //未読みつからず&現在タブが先頭ではなかったら、先頭タブから現在タブの手前まで探索
5883 if (idx == -1 && bgnIdx > 0)
5885 for (int i = 0; i < bgnIdx; i++)
5887 idx = _statuses.GetOldestUnreadIndex(ListTab.TabPages[i].Text);
5890 ListTab.SelectedIndex = i;
5891 lst = (DetailsListView)ListTab.TabPages[i].Tag;
5892 //_curTab = ListTab.TabPages[i];
5898 //全部調べたが未読見つからず→先頭タブの最新発言へ
5901 ListTab.SelectedIndex = 0;
5902 lst = (DetailsListView)ListTab.TabPages[0].Tag;
5903 //_curTab = ListTab.TabPages[0];
5904 if (_statuses.SortOrder == SortOrder.Ascending)
5905 idx = lst.VirtualListSize - 1;
5910 if (lst.VirtualListSize > 0 && idx > -1 && lst.VirtualListSize > idx)
5912 SelectListItem(lst, idx);
5913 if (_statuses.SortMode == IdComparerClass.ComparerMode.Id)
5915 if (_statuses.SortOrder == SortOrder.Ascending && lst.Items[idx].Position.Y > lst.ClientSize.Height - _iconSz - 10 ||
5916 _statuses.SortOrder == SortOrder.Descending && lst.Items[idx].Position.Y < _iconSz + 10)
5922 lst.EnsureVisible(idx);
5927 lst.EnsureVisible(idx);
5933 private void StatusOpenMenuItem_Click(object sender, EventArgs e)
5935 if (_curList.SelectedIndices.Count > 0 && _statuses.Tabs[_curTab.Text].TabType != MyCommon.TabUsageType.DirectMessage)
5937 var post = _statuses[_curTab.Text, _curList.SelectedIndices[0]];
5938 OpenUriAsync(MyCommon.GetStatusUrl(post));
5942 private void FavorareMenuItem_Click(object sender, EventArgs e)
5944 if (_curList.SelectedIndices.Count > 0)
5946 PostClass post = _statuses[_curTab.Text, _curList.SelectedIndices[0]];
5947 OpenUriAsync(Properties.Resources.FavstarUrl + "users/" + post.ScreenName + "/recent");
5951 private void VerUpMenuItem_Click(object sender, EventArgs e)
5956 private void RunTweenUp()
5958 ProcessStartInfo pinfo = new ProcessStartInfo();
5959 pinfo.UseShellExecute = true;
5960 pinfo.WorkingDirectory = MyCommon.settingPath;
5961 pinfo.FileName = Path.Combine(MyCommon.settingPath, "TweenUp3.exe");
5962 pinfo.Arguments = "\"" + Application.StartupPath + "\"";
5965 Process.Start(pinfo);
5969 MessageBox.Show("Failed to execute TweenUp3.exe.");
5973 private void CheckNewVersion(bool startup = false)
5975 if (string.IsNullOrEmpty(MyCommon.fileVersion))
5983 retMsg = tw.GetVersionInfo();
5990 if (string.IsNullOrEmpty(retMsg))
5992 StatusLabel.Text = Properties.Resources.CheckNewVersionText9;
5993 if (!startup) MessageBox.Show(Properties.Resources.CheckNewVersionText10, MyCommon.ReplaceAppName(Properties.Resources.CheckNewVersionText2), MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2);
5997 // 改行2つで前後パートを分割(前半がバージョン番号など、後半が詳細テキスト)
5998 string[] msgPart = retMsg.Split(new string[] {"\n\n", "\r\n\r\n"}, 2, StringSplitOptions.None);
6000 string[] msgHeader = msgPart[0].Split(new string[] {"\n", "\r\n"}, StringSplitOptions.None);
6001 string msgBody = msgPart.Length == 2 ? msgPart[1] : "";
6003 msgBody = Regex.Replace(msgBody, "(?<!\r)\n", "\r\n"); // LF -> CRLF
6005 string currentVersion = msgHeader[0];
6006 string downloadUrl = msgHeader[1];
6008 if (currentVersion.Replace(".", "").CompareTo(MyCommon.fileVersion.Replace(".", "")) > 0)
6010 using (var dialog = new UpdateDialog())
6012 dialog.SummaryText = string.Format(Properties.Resources.CheckNewVersionText3, MyCommon.GetReadableVersion(currentVersion));
6013 dialog.DetailsText = msgBody;
6014 if (dialog.ShowDialog(this) == DialogResult.Yes)
6016 this.OpenUriAsync(downloadUrl);
6024 var msgtext = MyCommon.ReplaceAppName(string.Format(Properties.Resources.CheckNewVersionText7, MyCommon.GetReadableVersion(), MyCommon.GetReadableVersion(currentVersion)));
6025 MessageBox.Show(msgtext, MyCommon.ReplaceAppName(Properties.Resources.CheckNewVersionText2), MessageBoxButtons.OK, MessageBoxIcon.Information);
6030 private void Colorize()
6034 //件数関連の場合、タイトル即時書き換え
6035 if (SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.None &&
6036 SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.Post &&
6037 SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.Ver &&
6038 SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.OwnStatus)
6040 SetMainWindowTitle();
6042 if (!StatusLabelUrl.Text.StartsWith("http")) SetStatusLabelUrl();
6043 foreach (TabPage tb in ListTab.TabPages)
6045 if (_statuses.Tabs[tb.Text].UnreadCount == 0)
6047 if (SettingDialog.TabIconDisp)
6049 if (tb.ImageIndex == 0) tb.ImageIndex = -1;
6053 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
6056 public string createDetailHtml(string orgdata)
6058 return detailHtmlFormatHeader + orgdata + detailHtmlFormatFooter;
6061 private void DisplayItemImage_Downloaded(object sender, EventArgs e)
6063 if (sender.Equals(displayItem))
6065 if (UserPicture.Image != null) UserPicture.Image.Dispose();
6066 if (displayItem.Image != null)
6070 UserPicture.Image = new Bitmap(displayItem.Image);
6074 UserPicture.Image = null;
6079 UserPicture.Image = null;
6084 private void DispSelectedPost()
6086 DispSelectedPost(false);
6089 private static PostClass displaypost = new PostClass();
6091 private void DispSelectedPost(bool forceupdate)
6093 if (_curList.SelectedIndices.Count == 0 || _curPost == null)
6096 if (!forceupdate && _curPost.Equals(displaypost))
6099 displaypost = _curPost;
6100 if (displayItem != null)
6102 displayItem.ImageDownloaded -= this.DisplayItemImage_Downloaded;
6105 displayItem = (ImageListViewItem)_curList.Items[_curList.SelectedIndices[0]];
6106 displayItem.ImageDownloaded += this.DisplayItemImage_Downloaded;
6108 string dTxt = createDetailHtml(_curPost.IsDeleted ? "(DELETED)" : _curPost.Text);
6111 SourceLinkLabel.Tag = null;
6112 SourceLinkLabel.Text = "";
6116 Match mc = Regex.Match(_curPost.SourceHtml, "<a href=\"(?<sourceurl>.+?)\"");
6119 string src = mc.Groups["sourceurl"].Value;
6120 SourceLinkLabel.Tag = mc.Groups["sourceurl"].Value;
6121 mc = Regex.Match(src, "^https?://");
6124 src = src.Insert(0, "http://twitter.com");
6126 SourceLinkLabel.Tag = src;
6130 SourceLinkLabel.Tag = null;
6132 if (string.IsNullOrEmpty(_curPost.Source))
6134 SourceLinkLabel.Text = "";
6135 //SourceLinkLabel.Visible = false;
6139 SourceLinkLabel.Text = _curPost.Source;
6140 //SourceLinkLabel.Visible = true;
6143 SourceLinkLabel.TabStop = false;
6145 if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage && !_curPost.IsOwl)
6147 NameLabel.Text = "DM TO -> ";
6149 else if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage)
6151 NameLabel.Text = "DM FROM <- ";
6155 NameLabel.Text = "";
6157 NameLabel.Text += _curPost.ScreenName + "/" + _curPost.Nickname;
6158 NameLabel.Tag = _curPost.ScreenName;
6159 if (!string.IsNullOrEmpty(_curPost.RetweetedBy))
6161 NameLabel.Text += " (RT:" + _curPost.RetweetedBy + ")";
6163 if (UserPicture.Image != null) UserPicture.Image.Dispose();
6164 if (!string.IsNullOrEmpty(_curPost.ImageUrl) && TIconDic[_curPost.ImageUrl] != null)
6168 UserPicture.Image = new Bitmap(TIconDic[_curPost.ImageUrl]);
6172 UserPicture.Image = null;
6177 UserPicture.Image = null;
6180 NameLabel.ForeColor = System.Drawing.SystemColors.ControlText;
6181 DateTimeLabel.Text = _curPost.CreatedAt.ToString();
6182 if (_curPost.IsOwl && (SettingDialog.OneWayLove || _statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage)) NameLabel.ForeColor = _clOWL;
6183 if (_curPost.RetweetedId > 0) NameLabel.ForeColor = _clRetweet;
6184 if (_curPost.IsFav) NameLabel.ForeColor = _clFav;
6186 if (DumpPostClassToolStripMenuItem.Checked)
6188 StringBuilder sb = new StringBuilder(512);
6190 sb.Append("-----Start PostClass Dump<br>");
6191 sb.AppendFormat("TextFromApi : {0}<br>", _curPost.TextFromApi);
6192 sb.AppendFormat("(PlainText) : <xmp>{0}</xmp><br>", _curPost.TextFromApi);
6193 sb.AppendFormat("StatusId : {0}<br>", _curPost.StatusId.ToString());
6194 //sb.AppendFormat("ImageIndex : {0}<br>", _curPost.ImageIndex.ToString());
6195 sb.AppendFormat("ImageUrl : {0}<br>", _curPost.ImageUrl);
6196 sb.AppendFormat("InReplyToStatusId : {0}<br>", _curPost.InReplyToStatusId.ToString());
6197 sb.AppendFormat("InReplyToUser : {0}<br>", _curPost.InReplyToUser);
6198 sb.AppendFormat("IsDM : {0}<br>", _curPost.IsDm.ToString());
6199 sb.AppendFormat("IsFav : {0}<br>", _curPost.IsFav.ToString());
6200 sb.AppendFormat("IsMark : {0}<br>", _curPost.IsMark.ToString());
6201 sb.AppendFormat("IsMe : {0}<br>", _curPost.IsMe.ToString());
6202 sb.AppendFormat("IsOwl : {0}<br>", _curPost.IsOwl.ToString());
6203 sb.AppendFormat("IsProtect : {0}<br>", _curPost.IsProtect.ToString());
6204 sb.AppendFormat("IsRead : {0}<br>", _curPost.IsRead.ToString());
6205 sb.AppendFormat("IsReply : {0}<br>", _curPost.IsReply.ToString());
6207 foreach (string nm in _curPost.ReplyToList)
6209 sb.AppendFormat("ReplyToList : {0}<br>", nm);
6212 sb.AppendFormat("ScreenName : {0}<br>", _curPost.ScreenName);
6213 sb.AppendFormat("NickName : {0}<br>", _curPost.Nickname);
6214 sb.AppendFormat("Text : {0}<br>", _curPost.Text);
6215 sb.AppendFormat("(PlainText) : <xmp>{0}</xmp><br>", _curPost.Text);
6216 sb.AppendFormat("CreatedAt : {0}<br>", _curPost.CreatedAt.ToString());
6217 sb.AppendFormat("Source : {0}<br>", _curPost.Source);
6218 sb.AppendFormat("UserId : {0}<br>", _curPost.UserId);
6219 sb.AppendFormat("FilterHit : {0}<br>", _curPost.FilterHit);
6220 sb.AppendFormat("RetweetedBy : {0}<br>", _curPost.RetweetedBy);
6221 sb.AppendFormat("RetweetedId : {0}<br>", _curPost.RetweetedId);
6222 sb.AppendFormat("SearchTabName : {0}<br>", _curPost.RelTabName);
6223 sb.Append("-----End PostClass Dump<br>");
6225 PostBrowser.Visible = false;
6226 PostBrowser.DocumentText = detailHtmlFormatHeader + sb.ToString() + detailHtmlFormatFooter;
6227 PostBrowser.Visible = true;
6233 if (PostBrowser.DocumentText != dTxt)
6235 PostBrowser.Visible = false;
6236 PostBrowser.DocumentText = dTxt;
6238 this.SplitContainer3.Panel2Collapsed = true;
6240 if (this.IsPreviewEnable)
6241 this.tweetThumbnail1.ShowThumbnailAsync(_curPost);
6244 catch (System.Runtime.InteropServices.COMException)
6248 catch (UriFormatException)
6250 PostBrowser.DocumentText = dTxt;
6254 PostBrowser.Visible = true;
6259 private void MatomeMenuItem_Click(object sender, EventArgs e)
6261 OpenApplicationWebsite();
6264 private void OpenApplicationWebsite()
6266 OpenUriAsync(ApplicationSettings.WebsiteUrl);
6269 private void ShortcutKeyListMenuItem_Click(object sender, EventArgs e)
6271 OpenUriAsync(ApplicationSettings.ShortcutKeyUrl);
6274 private void ListTab_KeyDown(object sender, KeyEventArgs e)
6276 if (ListTab.SelectedTab != null)
6278 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.PublicSearch)
6280 Control pnl = ListTab.SelectedTab.Controls["panelSearch"];
6281 if (pnl.Controls["comboSearch"].Focused ||
6282 pnl.Controls["comboLang"].Focused ||
6283 pnl.Controls["buttonSearch"].Focused) return;
6285 ModifierState State = GetModifierState(e.Control, e.Shift, e.Alt);
6286 if (State == ModifierState.NotFlags) return;
6287 if (State != ModifierState.None) _anchorFlag = false;
6288 if (CommonKeyDown(e.KeyCode, FocusedControl.ListTab, State))
6291 e.SuppressKeyPress = true;
6296 private ModifierState GetModifierState(bool sControl, bool sShift, bool sAlt)
6298 ModifierState state = ModifierState.None;
6299 if (sControl) state = state | ModifierState.Ctrl;
6300 if (sShift) state = state | ModifierState.Shift;
6301 if (sAlt) state = state | ModifierState.Alt;
6306 private enum ModifierState
6318 //PostBrowser = 102,
6322 private enum FocusedControl : int
6330 private bool CommonKeyDown(Keys KeyCode, FocusedControl Focused, ModifierState Modifier)
6332 //リストのカーソル移動関係(上下キー、PageUp/Downに該当)
6333 if (Focused == FocusedControl.ListTab)
6335 if (Modifier == (ModifierState.Ctrl | ModifierState.Shift) ||
6336 Modifier == ModifierState.Ctrl ||
6337 Modifier == ModifierState.None ||
6338 Modifier == ModifierState.Shift)
6340 if (KeyCode == Keys.J)
6342 SendKeys.Send("{DOWN}");
6345 else if (KeyCode == Keys.K)
6347 SendKeys.Send("{UP}");
6351 if (Modifier == ModifierState.Shift ||
6352 Modifier == ModifierState.None)
6354 if (KeyCode == Keys.F)
6356 SendKeys.Send("{PGDN}");
6359 else if (KeyCode == Keys.B)
6361 SendKeys.Send("{PGUP}");
6370 case ModifierState.None:
6375 OpenApplicationWebsite();
6378 MenuItemSearchNext_Click(null, null);
6384 GetTimeline(MyCommon.WORKERTYPE.Reply, 1, 0, "");
6387 GetTimeline(MyCommon.WORKERTYPE.DirectMessegeRcv, 1, 0, "");
6390 if (Focused != FocusedControl.StatusText)
6396 case Keys.ProcessKey:
6397 if (Focused == FocusedControl.ListTab) _anchorFlag = false;
6398 JumpUnreadMenuItem_Click(null, null);
6401 if (Focused == FocusedControl.ListTab) _anchorFlag = false;
6402 ShowRelatedStatusesMenuItem_Click(null, null);
6406 if (Focused == FocusedControl.ListTab)
6419 case Keys.OemPeriod:
6423 if (this.StatusText.Enabled) this.StatusText.Focus();
6426 MakeReplyOrDirectStatus();
6433 _anchorFlag = false;
6453 // ] in_reply_to参照元へ戻る
6454 GoInReplyToPostTree();
6457 // [ in_reply_toへジャンプ
6458 GoBackInReplyToPostTree();
6461 if (ListTab.SelectedTab != null)
6463 MyCommon.TabUsageType tabtype = _statuses.Tabs[ListTab.SelectedTab.Text].TabType;
6464 if (tabtype == MyCommon.TabUsageType.Related || tabtype == MyCommon.TabUsageType.UserTimeline || tabtype == MyCommon.TabUsageType.PublicSearch)
6466 TabPage relTp = ListTab.SelectedTab;
6467 RemoveSpecifiedTab(relTp.Text, false);
6476 case ModifierState.Ctrl:
6481 MakeReplyOrDirectStatus(false, true);
6487 MakeReplyOrDirectStatus(false, false);
6490 FavoriteChange(true);
6493 doRepliedStatusOpen();
6499 ReadedStripMenuItem_Click(null, null);
6502 HashManageMenuItem_Click(null, null);
6505 UrlConvertAutoToolStripMenuItem_Click(null, null);
6508 if (Focused != FocusedControl.PostBrowser)
6510 MultiLineMenuItem_Click(null, null);
6515 MenuItemSubSearch_Click(null, null);
6522 MoveToHomeToolStripMenuItem_Click(null, null);
6526 MoveToFavToolStripMenuItem_Click(null, null);
6530 StatusOpenMenuItem_Click(null, null);
6534 OpenURLMenuItem_Click(null, null);
6538 if (Focused == FocusedControl.ListTab)
6545 return false; //スルーする
6563 // タブダイレクト選択(Ctrl+1~8,Ctrl+9)
6564 int tabNo = KeyCode - Keys.D1;
6565 if (ListTab.TabPages.Count < tabNo)
6567 ListTab.SelectedIndex = tabNo;
6568 ListTabSelect(ListTab.TabPages[tabNo]);
6571 ListTab.SelectedIndex = ListTab.TabPages.Count - 1;
6572 ListTabSelect(ListTab.TabPages[ListTab.TabPages.Count - 1]);
6576 else if (Focused == FocusedControl.StatusText)
6582 StatusText.SelectAll();
6586 if (!string.IsNullOrWhiteSpace(StatusText.Text))
6588 _history[_hisIdx] = new PostingStatus(StatusText.Text, _reply_to_id, _reply_to_name);
6590 if (KeyCode == Keys.Up)
6593 if (_hisIdx < 0) _hisIdx = 0;
6598 if (_hisIdx > _history.Count - 1) _hisIdx = _history.Count - 1;
6600 StatusText.Text = _history[_hisIdx].status;
6601 _reply_to_id = _history[_hisIdx].inReplyToId;
6602 _reply_to_name = _history[_hisIdx].inReplyToName;
6603 StatusText.SelectionStart = StatusText.Text.Length;
6607 if (ListTab.SelectedIndex == 0)
6609 ListTab.SelectedIndex = ListTab.TabCount - 1;
6613 ListTab.SelectedIndex -= 1;
6619 if (ListTab.SelectedIndex == ListTab.TabCount - 1)
6621 ListTab.SelectedIndex = 0;
6625 ListTab.SelectedIndex += 1;
6633 //フォーカスPostBrowserもしくは関係なし
6637 PostBrowser.Document.ExecCommand("SelectAll", false, null);
6641 string _selText = WebBrowser_GetSelectionText(ref PostBrowser);
6642 if (!string.IsNullOrEmpty(_selText))
6646 Clipboard.SetDataObject(_selText, false, 5, 100);
6648 catch (Exception ex)
6650 MessageBox.Show(ex.Message);
6655 MultiLineMenuItem.Checked = !MultiLineMenuItem.Checked;
6656 MultiLineMenuItem_Click(null, null);
6661 case ModifierState.Shift:
6666 MenuItemSearchPrev_Click(null, null);
6672 GetTimeline(MyCommon.WORKERTYPE.Reply, -1, 0, "");
6675 GetTimeline(MyCommon.WORKERTYPE.DirectMessegeRcv, -1, 0, "");
6679 if (Focused != FocusedControl.StatusText)
6681 if (KeyCode == Keys.R)
6688 if (Focused == FocusedControl.ListTab)
6708 GoBackInReplyToPostTree(true, false);
6711 GoBackInReplyToPostTree(true, true);
6715 // お気に入り前後ジャンプ(SHIFT+N←/P→)
6720 // お気に入り前後ジャンプ(SHIFT+N←/P→)
6724 this.GoBackSelectPostChain();
6729 case ModifierState.Alt:
6733 doReTweetOfficial(true);
6736 if (_curPost != null)
6738 doShowUserStatus(_curPost.ScreenName, false);
6743 ScrollDownPostBrowser(false);
6746 ScrollDownPostBrowser(true);
6749 PageDownPostBrowser(false);
6752 PageDownPostBrowser(true);
6755 if (Focused == FocusedControl.ListTab)
6757 // 別タブの同じ書き込みへ(ALT+←/→)
6758 if (KeyCode == Keys.Right)
6760 GoSamePostToAnotherTab(false);
6763 else if (KeyCode == Keys.Left)
6765 GoSamePostToAnotherTab(true);
6770 case ModifierState.Ctrl | ModifierState.Shift:
6774 MakeReplyOrDirectStatus(false, true, true);
6780 if (ListTab.SelectedTab != null)
6782 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.PublicSearch)
6784 ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"].Focus();
6790 FavoriteChange(false);
6793 UnreadStripMenuItem_Click(null, null);
6796 HashToggleMenuItem_Click(null, null);
6799 ImageSelectMenuItem_Click(null, null);
6805 FavorareMenuItem_Click(null, null);
6808 if (Focused == FocusedControl.StatusText)
6814 if (_curList != null && _curList.Items.Count != 0 &&
6815 _curList.SelectedIndices.Count > 0 && _curList.SelectedIndices[0] > 0)
6817 idx = _curList.SelectedIndices[0] - 1;
6818 SelectListItem(_curList, idx);
6819 _curList.EnsureVisible(idx);
6824 if (_curList != null && _curList.Items.Count != 0 && _curList.SelectedIndices.Count > 0
6825 && _curList.SelectedIndices[0] < _curList.Items.Count - 1)
6827 idx = _curList.SelectedIndices[0] + 1;
6828 SelectListItem(_curList, idx);
6829 _curList.EnsureVisible(idx);
6834 if (StatusText.SelectionStart > 0)
6836 int endidx = StatusText.SelectionStart - 1;
6837 string startstr = "";
6838 bool pressed = false;
6839 for (int i = StatusText.SelectionStart - 1; i >= 0; i--)
6841 char c = StatusText.Text[i];
6842 if (Char.IsLetterOrDigit(c) || c == '_')
6849 startstr = StatusText.Text.Substring(i + 1, endidx - i);
6850 int cnt = AtIdSupl.ItemCount;
6851 ShowSuplDialog(StatusText, AtIdSupl, startstr.Length + 1, startstr);
6852 if (AtIdSupl.ItemCount != cnt) _modifySettingAtId = true;
6857 startstr = StatusText.Text.Substring(i + 1, endidx - i);
6858 ShowSuplDialog(StatusText, HashSupl, startstr.Length + 1, startstr);
6870 else if (Focused == FocusedControl.ListTab)
6872 DetailsListView lst = (DetailsListView)ListTab.SelectedTab.Tag;
6884 // ソートダイレクト選択(Ctrl+Shift+1~8,Ctrl+Shift+9)
6885 int colNo = KeyCode - Keys.D1;
6886 if (lst.Columns.Count < colNo) return false;
6887 col = lst.Columns.Cast<ColumnHeader>().Where((x) => { return x.DisplayIndex == colNo; }).FirstOrDefault();
6888 if (col == null) return false;
6889 MyList_ColumnClick(lst, new ColumnClickEventArgs(col.Index));
6892 col = lst.Columns.Cast<ColumnHeader>().OrderByDescending((x) => { return x.DisplayIndex; }).First();
6893 MyList_ColumnClick(lst, new ColumnClickEventArgs(col.Index));
6898 case ModifierState.Ctrl | ModifierState.Alt:
6899 if (KeyCode == Keys.S)
6901 FavoritesRetweetOriginal();
6904 else if (KeyCode == Keys.R)
6906 FavoritesRetweetUnofficial();
6909 else if (KeyCode == Keys.H)
6911 OpenUserAppointUrl();
6915 case ModifierState.Alt | ModifierState.Shift:
6916 if (Focused == FocusedControl.PostBrowser)
6918 if (KeyCode == Keys.R)
6919 doReTweetUnofficial();
6920 else if (KeyCode == Keys.C)
6927 if (!this.ExistCurrentPost) return false;
6928 doTranslation(_curPost.TextFromApi);
6931 doReTweetUnofficial();
6937 this.tweetThumbnail1.ScrollUp();
6940 this.tweetThumbnail1.ScrollDown();
6943 if (Focused == FocusedControl.ListTab && KeyCode == Keys.Enter)
6945 if (!this.SplitContainer3.Panel2Collapsed)
6947 OpenThumbnailPicture(this.tweetThumbnail1.Thumbnail);
6957 private void ScrollDownPostBrowser(bool forward)
6959 HtmlDocument doc = PostBrowser.Document;
6960 if (doc == null) return;
6961 if (doc.Body == null) return;
6964 doc.Body.ScrollTop += SettingDialog.FontDetail.Height;
6966 doc.Body.ScrollTop -= SettingDialog.FontDetail.Height;
6969 private void PageDownPostBrowser(bool forward)
6971 HtmlDocument doc = PostBrowser.Document;
6972 if (doc == null) return;
6973 if (doc.Body == null) return;
6976 doc.Body.ScrollTop += PostBrowser.ClientRectangle.Height - SettingDialog.FontDetail.Height;
6978 doc.Body.ScrollTop -= PostBrowser.ClientRectangle.Height - SettingDialog.FontDetail.Height;
6981 private void GoNextTab(bool forward)
6983 int idx = ListTab.SelectedIndex;
6987 if (idx > ListTab.TabPages.Count - 1) idx = 0;
6992 if (idx < 0) idx = ListTab.TabPages.Count - 1;
6994 ListTab.SelectedIndex = idx;
6995 ListTabSelect(ListTab.TabPages[idx]);
6998 private void CopyStot()
7001 StringBuilder sb = new StringBuilder();
7002 bool IsProtected = false;
7004 if (this._curTab != null && this._statuses.GetTabByName(this._curTab.Text) != null) isDm = this._statuses.GetTabByName(this._curTab.Text).TabType == MyCommon.TabUsageType.DirectMessage;
7005 foreach (int idx in _curList.SelectedIndices)
7007 PostClass post = _statuses[_curTab.Text, idx];
7013 if (post.IsDeleted) continue;
7016 if (post.RetweetedId > 0)
7017 sb.AppendFormat("{0}:{1} [http://twitter.com/{0}/status/{2}]{3}", post.ScreenName, post.TextSingleLine, post.RetweetedId, Environment.NewLine);
7019 sb.AppendFormat("{0}:{1} [http://twitter.com/{0}/status/{2}]{3}", post.ScreenName, post.TextSingleLine, post.StatusId, Environment.NewLine);
7023 sb.AppendFormat("{0}:{1} [{2}]{3}", post.ScreenName, post.TextSingleLine, post.StatusId, Environment.NewLine);
7028 MessageBox.Show(Properties.Resources.CopyStotText1);
7032 clstr = sb.ToString();
7035 Clipboard.SetDataObject(clstr, false, 5, 100);
7037 catch (Exception ex)
7039 MessageBox.Show(ex.Message);
7044 private void CopyIdUri()
7047 StringBuilder sb = new StringBuilder();
7048 if (this._curTab == null) return;
7049 if (this._statuses.GetTabByName(this._curTab.Text) == null) return;
7050 if (this._statuses.GetTabByName(this._curTab.Text).TabType == MyCommon.TabUsageType.DirectMessage) return;
7051 foreach (int idx in _curList.SelectedIndices)
7053 var post = _statuses[_curTab.Text, idx];
7054 sb.Append(MyCommon.GetStatusUrl(post));
7058 clstr = sb.ToString();
7061 Clipboard.SetDataObject(clstr, false, 5, 100);
7063 catch (Exception ex)
7065 MessageBox.Show(ex.Message);
7070 private void GoFav(bool forward)
7072 if (_curList.VirtualListSize == 0) return;
7079 if (_curList.SelectedIndices.Count == 0)
7085 fIdx = _curList.SelectedIndices[0] + 1;
7086 if (fIdx > _curList.VirtualListSize - 1) return;
7088 toIdx = _curList.VirtualListSize;
7093 if (_curList.SelectedIndices.Count == 0)
7095 fIdx = _curList.VirtualListSize - 1;
7099 fIdx = _curList.SelectedIndices[0] - 1;
7100 if (fIdx < 0) return;
7106 for (int idx = fIdx; idx != toIdx; idx += stp)
7108 if (_statuses[_curTab.Text, idx].IsFav)
7110 SelectListItem(_curList, idx);
7111 _curList.EnsureVisible(idx);
7117 private void GoSamePostToAnotherTab(bool left)
7119 if (_curList.VirtualListSize == 0) return;
7125 if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage) return; // Directタブは対象外(見つかるはずがない)
7126 if (_curList.SelectedIndices.Count == 0) return; //未選択も処理しない
7128 targetId = GetCurTabPost(_curList.SelectedIndices[0]).StatusId;
7133 if (ListTab.SelectedIndex == 0)
7139 fIdx = ListTab.SelectedIndex - 1;
7147 if (ListTab.SelectedIndex == ListTab.TabCount - 1)
7153 fIdx = ListTab.SelectedIndex + 1;
7155 toIdx = ListTab.TabCount;
7160 for (int tabidx = fIdx; tabidx != toIdx; tabidx += stp)
7162 if (_statuses.Tabs[ListTab.TabPages[tabidx].Text].TabType == MyCommon.TabUsageType.DirectMessage) continue; // Directタブは対象外
7163 for (int idx = 0; idx < ((DetailsListView)ListTab.TabPages[tabidx].Tag).VirtualListSize; idx++)
7165 if (_statuses[ListTab.TabPages[tabidx].Text, idx].StatusId == targetId)
7167 ListTab.SelectedIndex = tabidx;
7168 ListTabSelect(ListTab.TabPages[tabidx]);
7169 SelectListItem(_curList, idx);
7170 _curList.EnsureVisible(idx);
7179 private void GoPost(bool forward)
7181 if (_curList.SelectedIndices.Count == 0 || _curPost == null) return;
7188 fIdx = _curList.SelectedIndices[0] + 1;
7189 if (fIdx > _curList.VirtualListSize - 1) return;
7190 toIdx = _curList.VirtualListSize;
7195 fIdx = _curList.SelectedIndices[0] - 1;
7196 if (fIdx < 0) return;
7202 if (_curPost.RetweetedId == 0)
7204 name = _curPost.ScreenName;
7208 name = _curPost.RetweetedBy;
7210 for (int idx = fIdx; idx != toIdx; idx += stp)
7212 if (_statuses[_curTab.Text, idx].RetweetedId == 0)
7214 if (_statuses[_curTab.Text, idx].ScreenName == name)
7216 SelectListItem(_curList, idx);
7217 _curList.EnsureVisible(idx);
7223 if (_statuses[_curTab.Text, idx].RetweetedBy == name)
7225 SelectListItem(_curList, idx);
7226 _curList.EnsureVisible(idx);
7233 private void GoRelPost(bool forward)
7235 if (_curList.SelectedIndices.Count == 0) return;
7242 fIdx = _curList.SelectedIndices[0] + 1;
7243 if (fIdx > _curList.VirtualListSize - 1) return;
7244 toIdx = _curList.VirtualListSize;
7249 fIdx = _curList.SelectedIndices[0] - 1;
7250 if (fIdx < 0) return;
7257 if (_curPost == null) return;
7258 _anchorPost = _curPost;
7263 if (_anchorPost == null) return;
7266 for (int idx = fIdx; idx != toIdx; idx += stp)
7268 PostClass post = _statuses[_curTab.Text, idx];
7269 if (post.ScreenName == _anchorPost.ScreenName ||
7270 post.RetweetedBy == _anchorPost.ScreenName ||
7271 post.ScreenName == _anchorPost.RetweetedBy ||
7272 (!string.IsNullOrEmpty(post.RetweetedBy) && post.RetweetedBy == _anchorPost.RetweetedBy) ||
7273 _anchorPost.ReplyToList.Contains(post.ScreenName.ToLower()) ||
7274 _anchorPost.ReplyToList.Contains(post.RetweetedBy.ToLower()) ||
7275 post.ReplyToList.Contains(_anchorPost.ScreenName.ToLower()) ||
7276 post.ReplyToList.Contains(_anchorPost.RetweetedBy.ToLower()))
7278 SelectListItem(_curList, idx);
7279 _curList.EnsureVisible(idx);
7285 private void GoAnchor()
7287 if (_anchorPost == null) return;
7288 int idx = _statuses.Tabs[_curTab.Text].IndexOf(_anchorPost.StatusId);
7289 if (idx == -1) return;
7291 SelectListItem(_curList, idx);
7292 _curList.EnsureVisible(idx);
7295 private void GoTopEnd(bool GoTop)
7302 _item = _curList.GetItemAt(0, 25);
7310 _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1);
7312 idx = _curList.VirtualListSize - 1;
7316 SelectListItem(_curList, idx);
7319 private void GoMiddle()
7326 _item = _curList.GetItemAt(0, 0);
7336 _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1);
7339 idx2 = _curList.VirtualListSize - 1;
7345 idx3 = (idx1 + idx2) / 2;
7347 SelectListItem(_curList, idx3);
7350 private void GoLast()
7352 if (_curList.VirtualListSize == 0) return;
7354 if (_statuses.SortOrder == SortOrder.Ascending)
7356 SelectListItem(_curList, _curList.VirtualListSize - 1);
7357 _curList.EnsureVisible(_curList.VirtualListSize - 1);
7361 SelectListItem(_curList, 0);
7362 _curList.EnsureVisible(0);
7366 private void MoveTop()
7368 if (_curList.SelectedIndices.Count == 0) return;
7369 int idx = _curList.SelectedIndices[0];
7370 if (_statuses.SortOrder == SortOrder.Ascending)
7372 _curList.EnsureVisible(_curList.VirtualListSize - 1);
7376 _curList.EnsureVisible(0);
7378 _curList.EnsureVisible(idx);
7381 private void GoInReplyToPostTree()
7383 if (_curPost == null) return;
7385 TabClass curTabClass = _statuses.Tabs[_curTab.Text];
7387 if (curTabClass.TabType == MyCommon.TabUsageType.PublicSearch && _curPost.InReplyToStatusId == 0 && _curPost.TextFromApi.Contains("@"))
7389 PostClass post = null;
7390 string r = tw.GetStatusApi(false, _curPost.StatusId, ref post);
7391 if (string.IsNullOrEmpty(r) && post != null)
7393 _curPost.InReplyToStatusId = post.InReplyToStatusId;
7394 _curPost.InReplyToUser = post.InReplyToUser;
7395 _curPost.IsReply = post.IsReply;
7397 _curList.RedrawItems(_curItemIndex, _curItemIndex, false);
7401 this.StatusLabel.Text = r;
7405 if (!(this.ExistCurrentPost && _curPost.InReplyToUser != null && _curPost.InReplyToStatusId > 0)) return;
7407 if (replyChains == null || (replyChains.Count > 0 && replyChains.Peek().InReplyToId != _curPost.StatusId))
7409 replyChains = new Stack<ReplyChain>();
7411 replyChains.Push(new ReplyChain(_curPost.StatusId, _curPost.InReplyToStatusId, _curTab));
7414 string inReplyToTabName;
7415 long inReplyToId = _curPost.InReplyToStatusId;
7416 string inReplyToUser = _curPost.InReplyToUser;
7417 Dictionary<long, PostClass> curTabPosts;
7419 if (_statuses.Tabs[_curTab.Text].IsInnerStorageTabType)
7420 curTabPosts = curTabClass.Posts;
7422 curTabPosts = _statuses.Posts;
7424 var inReplyToPosts = from tab in _statuses.Tabs.Values
7425 orderby tab != curTabClass
7426 from post in ((Dictionary<long, PostClass>)(tab.IsInnerStorageTabType ? tab.Posts : _statuses.Posts)).Values
7427 where post.StatusId == inReplyToId
7428 let index = tab.IndexOf(post.StatusId)
7430 select new {Tab = tab, Index = index};
7434 var inReplyPost = inReplyToPosts.First();
7435 inReplyToTabName = inReplyPost.Tab.TabName;
7436 inReplyToIndex = inReplyPost.Index;
7438 catch (InvalidOperationException)
7440 PostClass post = null;
7441 string r = tw.GetStatusApi(false, _curPost.InReplyToStatusId, ref post);
7442 if (string.IsNullOrEmpty(r) && post != null)
7445 _statuses.AddPost(post);
7446 _statuses.DistributePosts();
7447 //_statuses.SubmitUpdate(null, null, null, false);
7448 this.RefreshTimeline(false);
7451 var inReplyPost = inReplyToPosts.First();
7452 inReplyToTabName = inReplyPost.Tab.TabName;
7453 inReplyToIndex = inReplyPost.Index;
7455 catch (InvalidOperationException)
7457 OpenUriAsync("http://twitter.com/" + inReplyToUser + "/statuses/" + inReplyToId.ToString());
7463 this.StatusLabel.Text = r;
7464 OpenUriAsync("http://twitter.com/" + inReplyToUser + "/statuses/" + inReplyToId.ToString());
7469 TabPage tabPage = this.ListTab.TabPages.Cast<TabPage>().First((tp) => { return tp.Text == inReplyToTabName; });
7470 DetailsListView listView = (DetailsListView)tabPage.Tag;
7472 if (_curTab != tabPage)
7474 this.ListTab.SelectTab(tabPage);
7477 this.SelectListItem(listView, inReplyToIndex);
7478 listView.EnsureVisible(inReplyToIndex);
7481 private void GoBackInReplyToPostTree(bool parallel = false, bool isForward = true)
7483 if (_curPost == null) return;
7485 TabClass curTabClass = _statuses.Tabs[_curTab.Text];
7486 Dictionary<long, PostClass> curTabPosts = curTabClass.IsInnerStorageTabType ? curTabClass.Posts : _statuses.Posts;
7490 if (_curPost.InReplyToStatusId != 0)
7492 var posts = from t in _statuses.Tabs
7493 from p in t.Value.IsInnerStorageTabType ? t.Value.Posts : _statuses.Posts
7494 where p.Value.StatusId != _curPost.StatusId && p.Value.InReplyToStatusId == _curPost.InReplyToStatusId
7495 let indexOf = t.Value.IndexOf(p.Value.StatusId)
7497 orderby isForward ? indexOf : indexOf * -1
7498 orderby t.Value != curTabClass
7499 select new {Tab = t.Value, Post = p.Value, Index = indexOf};
7502 var postList = posts.ToList();
7503 for (int i = postList.Count - 1; i >= 0; i--)
7506 if (postList.FindIndex((pst) => { return pst.Post.StatusId == postList[index].Post.StatusId; }) != index)
7508 postList.RemoveAt(index);
7511 var post = postList.FirstOrDefault((pst) => { return pst.Tab == curTabClass && isForward ? pst.Index > _curItemIndex : pst.Index < _curItemIndex; });
7512 if (post == null) post = postList.FirstOrDefault((pst) => { return pst.Tab != curTabClass; });
7513 if (post == null) post = postList.First();
7514 this.ListTab.SelectTab(this.ListTab.TabPages.Cast<TabPage>().First((tp) => { return tp.Text == post.Tab.TabName; }));
7515 DetailsListView listView = (DetailsListView)this.ListTab.SelectedTab.Tag;
7516 SelectListItem(listView, post.Index);
7517 listView.EnsureVisible(post.Index);
7519 catch (InvalidOperationException)
7527 if (replyChains == null || replyChains.Count < 1)
7529 var posts = from t in _statuses.Tabs
7530 from p in t.Value.IsInnerStorageTabType ? t.Value.Posts : _statuses.Posts
7531 where p.Value.InReplyToStatusId == _curPost.StatusId
7532 let indexOf = t.Value.IndexOf(p.Value.StatusId)
7535 orderby t.Value != curTabClass
7536 select new {Tab = t.Value, Index = indexOf};
7539 var post = posts.First();
7540 this.ListTab.SelectTab(this.ListTab.TabPages.Cast<TabPage>().First((tp) => { return tp.Text == post.Tab.TabName; }));
7541 DetailsListView listView = (DetailsListView)this.ListTab.SelectedTab.Tag;
7542 SelectListItem(listView, post.Index);
7543 listView.EnsureVisible(post.Index);
7545 catch (InvalidOperationException)
7552 ReplyChain chainHead = replyChains.Pop();
7553 if (chainHead.InReplyToId == _curPost.StatusId)
7555 int idx = _statuses.Tabs[chainHead.OriginalTab.Text].IndexOf(chainHead.OriginalId);
7564 ListTab.SelectTab(chainHead.OriginalTab);
7570 SelectListItem(_curList, idx);
7571 _curList.EnsureVisible(idx);
7577 this.GoBackInReplyToPostTree(parallel);
7583 private void GoBackSelectPostChain()
7587 this.selectPostChains.Pop();
7588 Tuple<TabPage, PostClass> tabPostPair = this.selectPostChains.Pop();
7589 if (!this.ListTab.TabPages.Contains(tabPostPair.Item1)) return;
7590 this.ListTab.SelectedTab = tabPostPair.Item1;
7591 if (tabPostPair.Item2 != null && this._statuses.Tabs[this._curTab.Text].IndexOf(tabPostPair.Item2.StatusId) > -1)
7593 this.SelectListItem(this._curList, this._statuses.Tabs[this._curTab.Text].IndexOf(tabPostPair.Item2.StatusId));
7594 this._curList.EnsureVisible(this._statuses.Tabs[this._curTab.Text].IndexOf(tabPostPair.Item2.StatusId));
7597 catch (InvalidOperationException)
7602 private void PushSelectPostChain()
7604 if (this.selectPostChains.Count == 0 || (this.selectPostChains.Peek().Item1.Text != this._curTab.Text || this._curPost != this.selectPostChains.Peek().Item2))
7606 this.selectPostChains.Push(Tuple.Create(this._curTab, _curPost));
7610 private void TrimPostChain()
7612 if (this.selectPostChains.Count < 2000) return;
7613 Stack<Tuple<TabPage, PostClass>> p = new Stack<Tuple<TabPage, PostClass>>();
7614 for (int i = 0; i < 2000; i++)
7616 p.Push(this.selectPostChains.Pop());
7618 this.selectPostChains.Clear();
7619 for (int i = 0; i < 2000; i++)
7621 this.selectPostChains.Push(p.Pop());
7625 private bool GoStatus(long statusId)
7627 if (statusId == 0) return false;
7628 for (int tabidx = 0; tabidx < ListTab.TabCount; tabidx++)
7630 if (_statuses.Tabs[ListTab.TabPages[tabidx].Text].TabType != MyCommon.TabUsageType.DirectMessage && _statuses.Tabs[ListTab.TabPages[tabidx].Text].Contains(statusId))
7632 int idx = _statuses.Tabs[ListTab.TabPages[tabidx].Text].IndexOf(statusId);
7633 ListTab.SelectedIndex = tabidx;
7634 ListTabSelect(ListTab.TabPages[tabidx]);
7635 SelectListItem(_curList, idx);
7636 _curList.EnsureVisible(idx);
7643 private bool GoDirectMessage(long statusId)
7645 if (statusId == 0) return false;
7646 for (int tabidx = 0; tabidx < ListTab.TabCount; tabidx++)
7648 if (_statuses.Tabs[ListTab.TabPages[tabidx].Text].TabType == MyCommon.TabUsageType.DirectMessage && _statuses.Tabs[ListTab.TabPages[tabidx].Text].Contains(statusId))
7650 int idx = _statuses.Tabs[ListTab.TabPages[tabidx].Text].IndexOf(statusId);
7651 ListTab.SelectedIndex = tabidx;
7652 ListTabSelect(ListTab.TabPages[tabidx]);
7653 SelectListItem(_curList, idx);
7654 _curList.EnsureVisible(idx);
7661 private void MyList_MouseClick(object sender, MouseEventArgs e)
7663 _anchorFlag = false;
7666 private void StatusText_Enter(object sender, EventArgs e)
7668 // フォーカスの戻り先を StatusText に設定
7669 this.Tag = StatusText;
7670 StatusText.BackColor = _clInputBackcolor;
7673 public Color InputBackColor
7675 get { return _clInputBackcolor; }
7676 set { _clInputBackcolor = value; }
7679 private void StatusText_Leave(object sender, EventArgs e)
7681 // フォーカスがメニューに遷移しないならばフォーカスはタブに移ることを期待
7682 if (ListTab.SelectedTab != null && MenuStrip1.Tag == null) this.Tag = ListTab.SelectedTab.Tag;
7683 StatusText.BackColor = Color.FromKnownColor(KnownColor.Window);
7686 private void StatusText_KeyDown(object sender, KeyEventArgs e)
7688 ModifierState State = GetModifierState(e.Control, e.Shift, e.Alt);
7689 if (State == ModifierState.NotFlags) return;
7690 if (CommonKeyDown(e.KeyCode, FocusedControl.StatusText, State))
7693 e.SuppressKeyPress = true;
7696 this.StatusText_TextChanged(null, null);
7699 private void SaveConfigsAll(bool ifModified)
7703 SaveConfigsCommon();
7710 if (_modifySettingCommon) SaveConfigsCommon();
7711 if (_modifySettingLocal) SaveConfigsLocal();
7712 if (_modifySettingAtId) SaveConfigsAtId();
7716 private void SaveConfigsAtId()
7718 if (_ignoreConfigSave || !SettingDialog.UseAtIdSupplement && AtIdSupl == null) return;
7720 _modifySettingAtId = false;
7721 SettingAtIdList cfgAtId = new SettingAtIdList(AtIdSupl.GetItemList());
7725 private void SaveConfigsCommon()
7727 if (_ignoreConfigSave) return;
7729 _modifySettingCommon = false;
7732 _cfgCommon.UserName = tw.Username;
7733 _cfgCommon.UserId = tw.UserId;
7734 _cfgCommon.Password = tw.Password;
7735 _cfgCommon.Token = tw.AccessToken;
7736 _cfgCommon.TokenSecret = tw.AccessTokenSecret;
7737 _cfgCommon.UserAccounts = SettingDialog.UserAccounts;
7738 _cfgCommon.UserstreamStartup = SettingDialog.UserstreamStartup;
7739 _cfgCommon.UserstreamPeriod = SettingDialog.UserstreamPeriodInt;
7740 _cfgCommon.TimelinePeriod = SettingDialog.TimelinePeriodInt;
7741 _cfgCommon.ReplyPeriod = SettingDialog.ReplyPeriodInt;
7742 _cfgCommon.DMPeriod = SettingDialog.DMPeriodInt;
7743 _cfgCommon.PubSearchPeriod = SettingDialog.PubSearchPeriodInt;
7744 _cfgCommon.ListsPeriod = SettingDialog.ListsPeriodInt;
7745 _cfgCommon.UserTimelinePeriod = SettingDialog.UserTimelinePeriodInt;
7746 _cfgCommon.Read = SettingDialog.Readed;
7747 _cfgCommon.IconSize = SettingDialog.IconSz;
7748 _cfgCommon.UnreadManage = SettingDialog.UnreadManage;
7749 _cfgCommon.PlaySound = SettingDialog.PlaySound;
7750 _cfgCommon.OneWayLove = SettingDialog.OneWayLove;
7752 _cfgCommon.NameBalloon = SettingDialog.NameBalloon;
7753 _cfgCommon.PostCtrlEnter = SettingDialog.PostCtrlEnter;
7754 _cfgCommon.PostShiftEnter = SettingDialog.PostShiftEnter;
7755 _cfgCommon.CountApi = SettingDialog.CountApi;
7756 _cfgCommon.CountApiReply = SettingDialog.CountApiReply;
7757 _cfgCommon.PostAndGet = SettingDialog.PostAndGet;
7758 _cfgCommon.DispUsername = SettingDialog.DispUsername;
7759 _cfgCommon.MinimizeToTray = SettingDialog.MinimizeToTray;
7760 _cfgCommon.CloseToExit = SettingDialog.CloseToExit;
7761 _cfgCommon.DispLatestPost = SettingDialog.DispLatestPost;
7762 _cfgCommon.SortOrderLock = SettingDialog.SortOrderLock;
7763 _cfgCommon.TinyUrlResolve = SettingDialog.TinyUrlResolve;
7764 _cfgCommon.ShortUrlForceResolve = SettingDialog.ShortUrlForceResolve;
7765 _cfgCommon.PeriodAdjust = SettingDialog.PeriodAdjust;
7766 _cfgCommon.StartupVersion = SettingDialog.StartupVersion;
7767 _cfgCommon.StartupFollowers = SettingDialog.StartupFollowers;
7768 _cfgCommon.RestrictFavCheck = SettingDialog.RestrictFavCheck;
7769 _cfgCommon.AlwaysTop = SettingDialog.AlwaysTop;
7770 _cfgCommon.UrlConvertAuto = SettingDialog.UrlConvertAuto;
7771 _cfgCommon.Outputz = SettingDialog.OutputzEnabled;
7772 _cfgCommon.OutputzKey = SettingDialog.OutputzKey;
7773 _cfgCommon.OutputzUrlMode = SettingDialog.OutputzUrlmode;
7774 _cfgCommon.UseUnreadStyle = SettingDialog.UseUnreadStyle;
7775 _cfgCommon.DateTimeFormat = SettingDialog.DateTimeFormat;
7776 _cfgCommon.DefaultTimeOut = SettingDialog.DefaultTimeOut;
7777 _cfgCommon.RetweetNoConfirm = SettingDialog.RetweetNoConfirm;
7778 _cfgCommon.LimitBalloon = SettingDialog.LimitBalloon;
7779 _cfgCommon.EventNotifyEnabled = SettingDialog.EventNotifyEnabled;
7780 _cfgCommon.EventNotifyFlag = SettingDialog.EventNotifyFlag;
7781 _cfgCommon.IsMyEventNotifyFlag = SettingDialog.IsMyEventNotifyFlag;
7782 _cfgCommon.ForceEventNotify = SettingDialog.ForceEventNotify;
7783 _cfgCommon.FavEventUnread = SettingDialog.FavEventUnread;
7784 _cfgCommon.TranslateLanguage = SettingDialog.TranslateLanguage;
7785 _cfgCommon.EventSoundFile = SettingDialog.EventSoundFile;
7786 _cfgCommon.AutoShortUrlFirst = SettingDialog.AutoShortUrlFirst;
7787 _cfgCommon.TabIconDisp = SettingDialog.TabIconDisp;
7788 _cfgCommon.ReplyIconState = SettingDialog.ReplyIconState;
7789 _cfgCommon.ReadOwnPost = SettingDialog.ReadOwnPost;
7790 _cfgCommon.GetFav = SettingDialog.GetFav;
7791 _cfgCommon.IsMonospace = SettingDialog.IsMonospace;
7792 if (IdeographicSpaceToSpaceToolStripMenuItem != null &&
7793 IdeographicSpaceToSpaceToolStripMenuItem.IsDisposed == false)
7795 _cfgCommon.WideSpaceConvert = this.IdeographicSpaceToSpaceToolStripMenuItem.Checked;
7797 _cfgCommon.ReadOldPosts = SettingDialog.ReadOldPosts;
7798 _cfgCommon.UseSsl = SettingDialog.UseSsl;
7799 _cfgCommon.BilyUser = SettingDialog.BitlyUser;
7800 _cfgCommon.BitlyPwd = SettingDialog.BitlyPwd;
7801 _cfgCommon.ShowGrid = SettingDialog.ShowGrid;
7802 _cfgCommon.UseAtIdSupplement = SettingDialog.UseAtIdSupplement;
7803 _cfgCommon.UseHashSupplement = SettingDialog.UseHashSupplement;
7804 _cfgCommon.PreviewEnable = SettingDialog.PreviewEnable;
7805 _cfgCommon.Language = SettingDialog.Language;
7807 _cfgCommon.SortOrder = (int)_statuses.SortOrder;
7808 switch (_statuses.SortMode)
7810 case IdComparerClass.ComparerMode.Nickname: //ニックネーム
7811 _cfgCommon.SortColumn = 1;
7813 case IdComparerClass.ComparerMode.Data: //本文
7814 _cfgCommon.SortColumn = 2;
7816 case IdComparerClass.ComparerMode.Id: //時刻=発言Id
7817 _cfgCommon.SortColumn = 3;
7819 case IdComparerClass.ComparerMode.Name: //名前
7820 _cfgCommon.SortColumn = 4;
7822 case IdComparerClass.ComparerMode.Source: //Source
7823 _cfgCommon.SortColumn = 7;
7827 _cfgCommon.Nicoms = SettingDialog.Nicoms;
7828 _cfgCommon.HashTags = HashMgr.HashHistories;
7829 if (HashMgr.IsPermanent)
7831 _cfgCommon.HashSelected = HashMgr.UseHash;
7835 _cfgCommon.HashSelected = "";
7837 _cfgCommon.HashIsHead = HashMgr.IsHead;
7838 _cfgCommon.HashIsPermanent = HashMgr.IsPermanent;
7839 _cfgCommon.HashIsNotAddToAtReply = HashMgr.IsNotAddToAtReply;
7840 _cfgCommon.TwitterUrl = SettingDialog.TwitterApiUrl;
7841 _cfgCommon.TwitterSearchUrl = SettingDialog.TwitterSearchApiUrl;
7842 _cfgCommon.HotkeyEnabled = SettingDialog.HotkeyEnabled;
7843 _cfgCommon.HotkeyModifier = SettingDialog.HotkeyMod;
7844 _cfgCommon.HotkeyKey = SettingDialog.HotkeyKey;
7845 _cfgCommon.HotkeyValue = SettingDialog.HotkeyValue;
7846 _cfgCommon.BlinkNewMentions = SettingDialog.BlinkNewMentions;
7847 if (ToolStripFocusLockMenuItem != null &&
7848 ToolStripFocusLockMenuItem.IsDisposed == false)
7850 _cfgCommon.FocusLockToStatusText = this.ToolStripFocusLockMenuItem.Checked;
7852 _cfgCommon.UseAdditionalCount = SettingDialog.UseAdditionalCount;
7853 _cfgCommon.MoreCountApi = SettingDialog.MoreCountApi;
7854 _cfgCommon.FirstCountApi = SettingDialog.FirstCountApi;
7855 _cfgCommon.SearchCountApi = SettingDialog.SearchCountApi;
7856 _cfgCommon.FavoritesCountApi = SettingDialog.FavoritesCountApi;
7857 _cfgCommon.UserTimelineCountApi = SettingDialog.UserTimelineCountApi;
7858 _cfgCommon.TrackWord = tw.TrackWord;
7859 _cfgCommon.AllAtReply = tw.AllAtReply;
7860 _cfgCommon.OpenUserTimeline = SettingDialog.OpenUserTimeline;
7861 _cfgCommon.ListCountApi = SettingDialog.ListCountApi;
7862 _cfgCommon.UseImageService = ImageServiceCombo.SelectedIndex;
7863 _cfgCommon.ListDoubleClickAction = SettingDialog.ListDoubleClickAction;
7864 _cfgCommon.UserAppointUrl = SettingDialog.UserAppointUrl;
7865 _cfgCommon.HideDuplicatedRetweets = SettingDialog.HideDuplicatedRetweets;
7866 _cfgCommon.IsPreviewFoursquare = SettingDialog.IsPreviewFoursquare;
7867 _cfgCommon.MapThumbnailProvider = SettingDialog.MapThumbnailProvider;
7868 _cfgCommon.MapThumbnailHeight = SettingDialog.MapThumbnailHeight;
7869 _cfgCommon.MapThumbnailWidth = SettingDialog.MapThumbnailWidth;
7870 _cfgCommon.MapThumbnailZoom = SettingDialog.MapThumbnailZoom;
7871 _cfgCommon.IsListsIncludeRts = SettingDialog.IsListStatusesIncludeRts;
7872 _cfgCommon.TabMouseLock = SettingDialog.TabMouseLock;
7873 _cfgCommon.IsRemoveSameEvent = SettingDialog.IsRemoveSameEvent;
7874 _cfgCommon.IsUseNotifyGrowl = SettingDialog.IsNotifyUseGrowl;
7880 private void SaveConfigsLocal()
7882 if (_ignoreConfigSave) return;
7885 _modifySettingLocal = false;
7886 _cfgLocal.FormSize = _mySize;
7887 _cfgLocal.FormLocation = _myLoc;
7888 _cfgLocal.SplitterDistance = _mySpDis;
7889 _cfgLocal.PreviewDistance = _mySpDis3;
7890 _cfgLocal.StatusMultiline = StatusText.Multiline;
7891 _cfgLocal.StatusTextHeight = _mySpDis2;
7892 _cfgLocal.AdSplitterDistance = _myAdSpDis;
7893 _cfgLocal.StatusText = SettingDialog.Status;
7895 _cfgLocal.FontUnread = _fntUnread;
7896 _cfgLocal.ColorUnread = _clUnread;
7897 _cfgLocal.FontRead = _fntReaded;
7898 _cfgLocal.ColorRead = _clReaded;
7899 _cfgLocal.FontDetail = _fntDetail;
7900 _cfgLocal.ColorDetail = _clDetail;
7901 _cfgLocal.ColorDetailBackcolor = _clDetailBackcolor;
7902 _cfgLocal.ColorDetailLink = _clDetailLink;
7903 _cfgLocal.ColorFav = _clFav;
7904 _cfgLocal.ColorOWL = _clOWL;
7905 _cfgLocal.ColorRetweet = _clRetweet;
7906 _cfgLocal.ColorSelf = _clSelf;
7907 _cfgLocal.ColorAtSelf = _clAtSelf;
7908 _cfgLocal.ColorTarget = _clTarget;
7909 _cfgLocal.ColorAtTarget = _clAtTarget;
7910 _cfgLocal.ColorAtFromTarget = _clAtFromTarget;
7911 _cfgLocal.ColorAtTo = _clAtTo;
7912 _cfgLocal.ColorListBackcolor = _clListBackcolor;
7913 _cfgLocal.ColorInputBackcolor = _clInputBackcolor;
7914 _cfgLocal.ColorInputFont = _clInputFont;
7915 _cfgLocal.FontInputFont = _fntInputFont;
7917 _cfgLocal.BrowserPath = SettingDialog.BrowserPath;
7918 _cfgLocal.UseRecommendStatus = SettingDialog.UseRecommendStatus;
7919 _cfgLocal.ProxyType = SettingDialog.SelectedProxyType;
7920 _cfgLocal.ProxyAddress = SettingDialog.ProxyAddress;
7921 _cfgLocal.ProxyPort = SettingDialog.ProxyPort;
7922 _cfgLocal.ProxyUser = SettingDialog.ProxyUser;
7923 _cfgLocal.ProxyPassword = SettingDialog.ProxyPassword;
7924 if (_ignoreConfigSave) return;
7929 private void SaveConfigsTabs()
7931 SettingTabs tabSetting = new SettingTabs();
7932 for (int i = 0; i < ListTab.TabPages.Count; i++)
7934 if (_statuses.Tabs[ListTab.TabPages[i].Text].TabType != MyCommon.TabUsageType.Related) tabSetting.Tabs.Add(_statuses.Tabs[ListTab.TabPages[i].Text]);
7939 private void SaveLogMenuItem_Click(object sender, EventArgs e)
7941 DialogResult rslt = MessageBox.Show(string.Format(Properties.Resources.SaveLogMenuItem_ClickText1, Environment.NewLine),
7942 Properties.Resources.SaveLogMenuItem_ClickText2,
7943 MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
7944 if (rslt == DialogResult.Cancel) return;
7946 SaveFileDialog1.FileName = MyCommon.GetAssemblyName() + "Posts" + DateTime.Now.ToString("yyMMdd-HHmmss") + ".tsv";
7947 SaveFileDialog1.InitialDirectory = Application.ExecutablePath;
7948 SaveFileDialog1.Filter = Properties.Resources.SaveLogMenuItem_ClickText3;
7949 SaveFileDialog1.FilterIndex = 0;
7950 SaveFileDialog1.Title = Properties.Resources.SaveLogMenuItem_ClickText4;
7951 SaveFileDialog1.RestoreDirectory = true;
7953 if (SaveFileDialog1.ShowDialog() == DialogResult.OK)
7955 if (!SaveFileDialog1.ValidateNames) return;
7956 using (StreamWriter sw = new StreamWriter(SaveFileDialog1.FileName, false, Encoding.UTF8))
7958 if (rslt == DialogResult.Yes)
7961 for (int idx = 0; idx < _curList.VirtualListSize; idx++)
7963 PostClass post = _statuses[_curTab.Text, idx];
7964 string protect = "";
7965 if (post.IsProtect) protect = "Protect";
7966 sw.WriteLine(post.Nickname + "\t" +
7967 "\"" + post.TextFromApi.Replace("\n", "").Replace("\"", "\"\"") + "\"" + "\t" +
7968 post.CreatedAt.ToString() + "\t" +
7969 post.ScreenName + "\t" +
7970 post.StatusId.ToString() + "\t" +
7971 post.ImageUrl + "\t" +
7972 "\"" + post.Text.Replace("\n", "").Replace("\"", "\"\"") + "\"" + "\t" +
7978 foreach (int idx in _curList.SelectedIndices)
7980 PostClass post = _statuses[_curTab.Text, idx];
7981 string protect = "";
7982 if (post.IsProtect) protect = "Protect";
7983 sw.WriteLine(post.Nickname + "\t" +
7984 "\"" + post.TextFromApi.Replace("\n", "").Replace("\"", "\"\"") + "\"" + "\t" +
7985 post.CreatedAt.ToString() + "\t" +
7986 post.ScreenName + "\t" +
7987 post.StatusId.ToString() + "\t" +
7988 post.ImageUrl + "\t" +
7989 "\"" + post.Text.Replace("\n", "").Replace("\"", "\"\"") + "\"" + "\t" +
7995 this.TopMost = SettingDialog.AlwaysTop;
7998 private void PostBrowser_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
8000 ModifierState State = GetModifierState(e.Control, e.Shift, e.Alt);
8001 if (State == ModifierState.NotFlags) return;
8002 bool KeyRes = CommonKeyDown(e.KeyCode, FocusedControl.PostBrowser, State);
8005 e.IsInputKey = true;
8008 public bool TabRename(ref string tabName)
8011 string newTabText = null;
8012 using (InputTabName inputName = new InputTabName())
8014 inputName.TabName = tabName;
8015 inputName.ShowDialog();
8016 if (inputName.DialogResult == DialogResult.Cancel) return false;
8017 newTabText = inputName.TabName;
8019 this.TopMost = SettingDialog.AlwaysTop;
8020 if (!string.IsNullOrEmpty(newTabText))
8023 for (int i = 0; i < ListTab.TabCount; i++)
8025 if (ListTab.TabPages[i].Text == newTabText)
8027 string tmp = string.Format(Properties.Resources.Tabs_DoubleClickText1, newTabText);
8028 MessageBox.Show(tmp, Properties.Resources.Tabs_DoubleClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
8032 //タブ名のリスト作り直し(デフォルトタブ以外は再作成)
8033 for (int i = 0; i < ListTab.TabCount; i++)
8035 if (ListTab.TabPages[i].Text == tabName)
8037 ListTab.TabPages[i].Text = newTabText;
8040 _statuses.RenameTab(tabName, newTabText);
8042 for (int i = 0; i < ListTab.TabCount; i++)
8044 if (_statuses.IsDistributableTab(ListTab.TabPages[i].Text))
8046 if (ListTab.TabPages[i].Text == tabName)
8048 ListTab.TabPages[i].Text = newTabText;
8052 SaveConfigsCommon();
8054 _rclickTabName = newTabText;
8055 tabName = newTabText;
8064 private void ListTab_MouseClick(object sender, MouseEventArgs e)
8066 if (e.Button == MouseButtons.Middle)
8068 for (int i = 0; i < this.ListTab.TabPages.Count; i++)
8070 if (this.ListTab.GetTabRect(i).Contains(e.Location))
8072 this.RemoveSpecifiedTab(this.ListTab.TabPages[i].Text, true);
8073 this.SaveConfigsTabs();
8080 private void Tabs_DoubleClick(object sender, MouseEventArgs e)
8082 string tn = ListTab.SelectedTab.Text;
8086 private void Tabs_MouseDown(object sender, MouseEventArgs e)
8088 if (SettingDialog.TabMouseLock) return;
8089 Point cpos = new Point(e.X, e.Y);
8090 if (e.Button == MouseButtons.Left)
8092 for (int i = 0; i < ListTab.TabPages.Count; i++)
8094 if (this.ListTab.GetTabRect(i).Contains(e.Location))
8097 _tabMouseDownPoint = e.Location;
8108 private void Tabs_DragEnter(object sender, DragEventArgs e)
8110 if (e.Data.GetDataPresent(typeof(TabPage)))
8111 e.Effect = DragDropEffects.Move;
8113 e.Effect = DragDropEffects.None;
8116 private void Tabs_DragDrop(object sender, DragEventArgs e)
8118 if (!e.Data.GetDataPresent(typeof(TabPage))) return;
8123 Point cpos = new Point(e.X, e.Y);
8124 Point spos = ListTab.PointToClient(cpos);
8126 for (i = 0; i < ListTab.TabPages.Count; i++)
8128 Rectangle rect = ListTab.GetTabRect(i);
8129 if (rect.Left <= spos.X && spos.X <= rect.Right &&
8130 rect.Top <= spos.Y && spos.Y <= rect.Bottom)
8132 tn = ListTab.TabPages[i].Text;
8133 if (spos.X <= (rect.Left + rect.Right) / 2)
8142 //タブのないところにドロップ->最後尾へ移動
8143 if (string.IsNullOrEmpty(tn))
8145 tn = ListTab.TabPages[ListTab.TabPages.Count - 1].Text;
8147 i = ListTab.TabPages.Count - 1;
8150 TabPage tp = (TabPage)e.Data.GetData(typeof(TabPage));
8151 if (tp.Text == tn) return;
8153 ReOrderTab(tp.Text, tn, bef);
8156 public void ReOrderTab(string targetTabText, string baseTabText, bool isBeforeBaseTab)
8159 for (baseIndex = 0; baseIndex < ListTab.TabPages.Count; baseIndex++)
8161 if (ListTab.TabPages[baseIndex].Text == baseTabText) break;
8164 ListTab.SuspendLayout();
8167 for (int j = 0; j < ListTab.TabPages.Count; j++)
8169 if (ListTab.TabPages[j].Text == targetTabText)
8171 mTp = ListTab.TabPages[j];
8172 ListTab.TabPages.Remove(mTp);
8173 if (j < baseIndex) baseIndex -= 1;
8177 if (isBeforeBaseTab)
8178 ListTab.TabPages.Insert(baseIndex, mTp);
8180 ListTab.TabPages.Insert(baseIndex + 1, mTp);
8182 ListTab.ResumeLayout();
8187 private void MakeReplyOrDirectStatus(bool isAuto = true, bool isReply = true, bool isAll = false)
8189 //isAuto:true=先頭に挿入、false=カーソル位置に挿入
8190 //isReply:true=@,false=DM
8191 if (!StatusText.Enabled) return;
8192 if (_curList == null) return;
8193 if (_curTab == null) return;
8194 if (!this.ExistCurrentPost) return;
8196 // 複数あてリプライはReplyではなく通常ポスト
8197 //↑仕様変更で全部リプライ扱いでOK(先頭ドット付加しない)
8198 //090403暫定でドットを付加しないようにだけ修正。単独と複数の処理は統合できると思われる。
8199 //090513 all @ replies 廃止の仕様変更によりドット付加に戻し(syo68k)
8201 if (_curList.SelectedIndices.Count > 0)
8204 if (_curList.SelectedIndices.Count == 1 && !isAll && this.ExistCurrentPost)
8207 if ((_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.DirectMessage && isAuto) || (!isAuto && !isReply))
8210 StatusText.Text = "D " + _curPost.ScreenName + " " + StatusText.Text;
8211 StatusText.SelectionStart = StatusText.Text.Length;
8214 _reply_to_name = "";
8217 if (string.IsNullOrEmpty(StatusText.Text))
8221 // ステータステキストが入力されていない場合先頭に@ユーザー名を追加する
8222 StatusText.Text = "@" + _curPost.ScreenName + " ";
8223 if (_curPost.RetweetedId > 0)
8225 _reply_to_id = _curPost.RetweetedId;
8229 _reply_to_id = _curPost.StatusId;
8231 _reply_to_name = _curPost.ScreenName;
8239 //1件選んでEnter or DoubleClick
8240 if (StatusText.Text.Contains("@" + _curPost.ScreenName + " "))
8242 if (_reply_to_id > 0 && _reply_to_name == _curPost.ScreenName)
8245 if (_curPost.RetweetedId > 0)
8247 _reply_to_id = _curPost.RetweetedId;
8251 _reply_to_id = _curPost.StatusId;
8253 _reply_to_name = _curPost.ScreenName;
8257 if (!StatusText.Text.StartsWith("@"))
8260 if (StatusText.Text.StartsWith(". "))
8263 StatusText.Text = StatusText.Text.Insert(2, "@" + _curPost.ScreenName + " ");
8265 _reply_to_name = "";
8270 StatusText.Text = "@" + _curPost.ScreenName + " " + StatusText.Text;
8271 if (_curPost.RetweetedId > 0)
8273 _reply_to_id = _curPost.RetweetedId;
8277 _reply_to_id = _curPost.StatusId;
8279 _reply_to_name = _curPost.ScreenName;
8286 StatusText.Text = ". @" + _curPost.ScreenName + " " + StatusText.Text;
8287 //StatusText.Text = "@" + _curPost.ScreenName + " " + StatusText.Text;
8289 _reply_to_name = "";
8294 //1件選んでCtrl-Rの場合(返信先操作せず)
8295 int sidx = StatusText.SelectionStart;
8296 string id = "@" + _curPost.ScreenName + " ";
8299 if (StatusText.Text.Substring(sidx - 1, 1) != " ")
8304 StatusText.Text = StatusText.Text.Insert(sidx, id);
8306 //if (StatusText.Text.StartsWith("@"))
8309 // StatusText.Text = ". " + StatusText.Text.Insert(sidx, " @" + _curPost.ScreenName + " ");
8310 // sidx += 5 + _curPost.ScreenName.Length;
8315 // StatusText.Text = StatusText.Text.Insert(sidx, " @" + _curPost.ScreenName + " ");
8316 // sidx += 3 + _curPost.ScreenName.Length;
8318 StatusText.SelectionStart = sidx;
8321 //_reply_to_name = null;
8329 if (!isAuto && !isReply) return;
8331 //C-S-rか、複数の宛先を選択中にEnter/DoubleClick/C-r/C-S-r
8335 //Enter or DoubleClick
8337 string sTxt = StatusText.Text;
8338 if (!sTxt.StartsWith(". "))
8342 _reply_to_name = "";
8344 for (int cnt = 0; cnt < _curList.SelectedIndices.Count; cnt++)
8346 PostClass post = _statuses[_curTab.Text, _curList.SelectedIndices[cnt]];
8347 if (!sTxt.Contains("@" + post.ScreenName + " "))
8349 sTxt = sTxt.Insert(2, "@" + post.ScreenName + " ");
8350 //sTxt = "@" + post.ScreenName + " " + sTxt;
8353 StatusText.Text = sTxt;
8358 if (_curList.SelectedIndices.Count > 1)
8363 int sidx = StatusText.SelectionStart;
8364 for (int cnt = 0; cnt < _curList.SelectedIndices.Count; cnt++)
8366 PostClass post = _statuses[_curTab.Text, _curList.SelectedIndices[cnt]];
8367 if (!ids.Contains("@" + post.ScreenName + " ") &&
8368 !post.ScreenName.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase))
8370 ids += "@" + post.ScreenName + " ";
8374 foreach (string nm in post.ReplyToList)
8376 if (!ids.Contains("@" + nm + " ") &&
8377 !nm.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase))
8379 Match m = Regex.Match(post.TextFromApi, "[@@](?<id>" + nm + ")([^a-zA-Z0-9]|$)", RegexOptions.IgnoreCase);
8381 ids += "@" + m.Result("${id}") + " ";
8383 ids += "@" + nm + " ";
8388 if (ids.Length == 0) return;
8389 if (!StatusText.Text.StartsWith(". "))
8391 StatusText.Text = ". " + StatusText.Text;
8394 _reply_to_name = "";
8398 if (StatusText.Text.Substring(sidx - 1, 1) != " ")
8403 StatusText.Text = StatusText.Text.Insert(sidx, ids);
8405 //if (StatusText.Text.StartsWith("@"))
8407 // StatusText.Text = ". " + StatusText.Text.Insert(sidx, ids);
8408 // sidx += 2 + ids.Length;
8412 // StatusText.Text = StatusText.Text.Insert(sidx, ids);
8413 // sidx += 1 + ids.Length;
8415 StatusText.SelectionStart = sidx;
8421 //1件のみ選択のC-S-r(返信元付加する可能性あり)
8424 int sidx = StatusText.SelectionStart;
8425 PostClass post = _curPost;
8426 if (!ids.Contains("@" + post.ScreenName + " ") &&
8427 !post.ScreenName.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase))
8429 ids += "@" + post.ScreenName + " ";
8431 foreach (string nm in post.ReplyToList)
8433 if (!ids.Contains("@" + nm + " ") &&
8434 !nm.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase))
8436 Match m = Regex.Match(post.TextFromApi, "[@@](?<id>" + nm + ")([^a-zA-Z0-9]|$)", RegexOptions.IgnoreCase);
8438 ids += "@" + m.Result("${id}") + " ";
8440 ids += "@" + nm + " ";
8443 if (!string.IsNullOrEmpty(post.RetweetedBy))
8445 if (!ids.Contains("@" + post.RetweetedBy + " ") &&
8446 !post.RetweetedBy.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase))
8448 ids += "@" + post.RetweetedBy + " ";
8451 if (ids.Length == 0) return;
8452 if (string.IsNullOrEmpty(StatusText.Text))
8455 StatusText.Text = ids;
8456 StatusText.SelectionStart = ids.Length;
8458 if (post.RetweetedId > 0)
8460 _reply_to_id = post.RetweetedId;
8464 _reply_to_id = post.StatusId;
8466 _reply_to_name = post.ScreenName;
8472 if (StatusText.Text.Substring(sidx - 1, 1) != " ")
8477 StatusText.Text = StatusText.Text.Insert(sidx, ids);
8479 StatusText.SelectionStart = sidx;
8485 StatusText.SelectionStart = StatusText.Text.Length;
8490 private void ListTab_MouseUp(object sender, MouseEventArgs e)
8495 private static int iconCnt = 0;
8496 private static int blinkCnt = 0;
8497 private static bool blink = false;
8498 private static bool idle = false;
8500 private void RefreshTasktrayIcon(bool forceRefresh)
8502 if (_colorize) Colorize();
8503 if (!TimerRefreshIcon.Enabled) return;
8504 //Static usCheckCnt As int = 0
8506 //Static iconDlListTopItem As ListViewItem = null
8508 if (forceRefresh) idle = false;
8510 //if (((ListView)ListTab.SelectedTab.Tag).TopItem == iconDlListTopItem)
8511 // ((ImageDictionary)this.TIconDic).PauseGetImage = false;
8513 // ((ImageDictionary)this.TIconDic).PauseGetImage = true;
8515 //iconDlListTopItem = ((ListView)ListTab.SelectedTab.Tag).TopItem;
8521 //if (usCheckCnt > 300) //1min
8524 // if (!this.IsReceivedUserStream)
8526 // TraceOut("ReconnectUserStream");
8527 // tw.ReconnectUserStream();
8532 foreach (BackgroundWorker bw in this._bw)
8534 if (bw != null && bw.IsBusy)
8549 SaveConfigsAll(true);
8554 NotifyIcon1.Icon = NIconRefresh[iconCnt];
8556 _myStatusError = false;
8560 TabClass tb = _statuses.GetTabByType(MyCommon.TabUsageType.Mentions);
8561 if (SettingDialog.ReplyIconState != MyCommon.REPLY_ICONSTATE.None && tb != null && tb.UnreadCount > 0)
8563 if (blinkCnt > 0) return;
8565 if (blink || SettingDialog.ReplyIconState == MyCommon.REPLY_ICONSTATE.StaticIcon)
8567 NotifyIcon1.Icon = ReplyIcon;
8571 NotifyIcon1.Icon = ReplyIconBlink;
8579 //優先度:エラー→オフライン→アイドル
8583 NotifyIcon1.Icon = NIconAtRed;
8586 if (_myStatusOnline)
8588 NotifyIcon1.Icon = NIconAt;
8592 NotifyIcon1.Icon = NIconAtSmoke;
8596 private void TimerRefreshIcon_Tick(object sender, EventArgs e)
8599 this.RefreshTasktrayIcon(false);
8602 private void ContextMenuTabProperty_Opening(object sender, CancelEventArgs e)
8604 //右クリックの場合はタブ名が設定済。アプリケーションキーの場合は現在のタブを対象とする
8605 if (string.IsNullOrEmpty(_rclickTabName) || sender != ContextMenuTabProperty)
8607 if (ListTab != null && ListTab.SelectedTab != null)
8608 _rclickTabName = ListTab.SelectedTab.Text;
8613 if (_statuses == null) return;
8614 if (_statuses.Tabs == null) return;
8616 TabClass tb = _statuses.Tabs[_rclickTabName];
8617 if (tb == null) return;
8619 NotifyDispMenuItem.Checked = tb.Notify;
8620 this.NotifyTbMenuItem.Checked = tb.Notify;
8622 soundfileListup = true;
8623 SoundFileComboBox.Items.Clear();
8624 this.SoundFileTbComboBox.Items.Clear();
8625 SoundFileComboBox.Items.Add("");
8626 this.SoundFileTbComboBox.Items.Add("");
8627 DirectoryInfo oDir = new DirectoryInfo(Application.StartupPath + Path.DirectorySeparatorChar);
8628 if (Directory.Exists(Path.Combine(Application.StartupPath, "Sounds")))
8630 oDir = oDir.GetDirectories("Sounds")[0];
8632 foreach (FileInfo oFile in oDir.GetFiles("*.wav"))
8634 SoundFileComboBox.Items.Add(oFile.Name);
8635 this.SoundFileTbComboBox.Items.Add(oFile.Name);
8637 int idx = SoundFileComboBox.Items.IndexOf(tb.SoundFile);
8638 if (idx == -1) idx = 0;
8639 SoundFileComboBox.SelectedIndex = idx;
8640 this.SoundFileTbComboBox.SelectedIndex = idx;
8641 soundfileListup = false;
8642 UreadManageMenuItem.Checked = tb.UnreadManage;
8643 this.UnreadMngTbMenuItem.Checked = tb.UnreadManage;
8645 TabMenuControl(_rclickTabName);
8648 private void TabMenuControl(string tabName)
8650 this.FilterEditMenuItem.Enabled = true;
8651 this.EditRuleTbMenuItem.Enabled = true;
8653 if (_statuses.IsDefaultTab(tabName))
8655 this.ProtectTabMenuItem.Enabled = false;
8656 this.ProtectTbMenuItem.Enabled = false;
8660 this.ProtectTabMenuItem.Enabled = true;
8661 this.ProtectTbMenuItem.Enabled = true;
8664 if (_statuses.IsDefaultTab(tabName) || _statuses.Tabs[tabName].Protected)
8666 this.ProtectTabMenuItem.Checked = true;
8667 this.ProtectTbMenuItem.Checked = true;
8668 this.DeleteTabMenuItem.Enabled = false;
8669 this.DeleteTbMenuItem.Enabled = false;
8673 this.ProtectTabMenuItem.Checked = false;
8674 this.ProtectTbMenuItem.Checked = false;
8675 this.DeleteTabMenuItem.Enabled = true;
8676 this.DeleteTbMenuItem.Enabled = true;
8680 private void ProtectTabMenuItem_Click(object sender, EventArgs e)
8682 var checkState = ((ToolStripMenuItem)sender).Checked;
8685 this.ProtectTbMenuItem.Checked = checkState;
8686 this.ProtectTabMenuItem.Checked = checkState;
8689 this.DeleteTabMenuItem.Enabled = !checkState;
8690 this.DeleteTbMenuItem.Enabled = !checkState;
8692 if (string.IsNullOrEmpty(_rclickTabName)) return;
8693 _statuses.Tabs[_rclickTabName].Protected = checkState;
8698 private void UreadManageMenuItem_Click(object sender, EventArgs e)
8700 UreadManageMenuItem.Checked = ((ToolStripMenuItem)sender).Checked;
8701 this.UnreadMngTbMenuItem.Checked = UreadManageMenuItem.Checked;
8703 if (string.IsNullOrEmpty(_rclickTabName)) return;
8704 ChangeTabUnreadManage(_rclickTabName, UreadManageMenuItem.Checked);
8709 public void ChangeTabUnreadManage(string tabName, bool isManage)
8712 for (idx = 0; idx < ListTab.TabCount; idx++)
8714 if (ListTab.TabPages[idx].Text == tabName) break;
8717 _statuses.SetTabUnreadManage(tabName, isManage);
8718 if (SettingDialog.TabIconDisp)
8720 if (_statuses.Tabs[tabName].UnreadCount > 0)
8721 ListTab.TabPages[idx].ImageIndex = 0;
8723 ListTab.TabPages[idx].ImageIndex = -1;
8726 if (_curTab.Text == tabName)
8733 SetMainWindowTitle();
8734 SetStatusLabelUrl();
8735 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
8738 private void NotifyDispMenuItem_Click(object sender, EventArgs e)
8740 NotifyDispMenuItem.Checked = ((ToolStripMenuItem)sender).Checked;
8741 this.NotifyTbMenuItem.Checked = NotifyDispMenuItem.Checked;
8743 if (string.IsNullOrEmpty(_rclickTabName)) return;
8745 _statuses.Tabs[_rclickTabName].Notify = NotifyDispMenuItem.Checked;
8750 private void SoundFileComboBox_SelectedIndexChanged(object sender, EventArgs e)
8752 if (soundfileListup || string.IsNullOrEmpty(_rclickTabName)) return;
8754 _statuses.Tabs[_rclickTabName].SoundFile = (string)((ToolStripComboBox)sender).SelectedItem;
8759 private void DeleteTabMenuItem_Click(object sender, EventArgs e)
8761 if (string.IsNullOrEmpty(_rclickTabName) || sender == this.DeleteTbMenuItem) _rclickTabName = ListTab.SelectedTab.Text;
8763 RemoveSpecifiedTab(_rclickTabName, true);
8767 private void FilterEditMenuItem_Click(object sender, EventArgs e)
8769 if (string.IsNullOrEmpty(_rclickTabName)) _rclickTabName = _statuses.GetTabByType(MyCommon.TabUsageType.Home).TabName;
8770 fltDialog.SetCurrent(_rclickTabName);
8771 fltDialog.ShowDialog(this);
8772 this.TopMost = SettingDialog.AlwaysTop;
8776 this.Cursor = Cursors.WaitCursor;
8781 _statuses.FilterAll();
8782 foreach (TabPage tb in ListTab.TabPages)
8784 ((DetailsListView)tb.Tag).VirtualListSize = _statuses.Tabs[tb.Text].AllCount;
8785 if (_statuses.Tabs[tb.Text].UnreadCount > 0)
8787 if (SettingDialog.TabIconDisp)
8792 if (SettingDialog.TabIconDisp)
8796 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
8800 this.Cursor = Cursors.Default;
8805 private void AddTabMenuItem_Click(object sender, EventArgs e)
8807 string tabName = null;
8808 MyCommon.TabUsageType tabUsage;
8809 using (InputTabName inputName = new InputTabName())
8811 inputName.TabName = _statuses.GetUniqueTabName();
8812 inputName.IsShowUsage = true;
8813 inputName.ShowDialog();
8814 if (inputName.DialogResult == DialogResult.Cancel) return;
8815 tabName = inputName.TabName;
8816 tabUsage = inputName.Usage;
8818 this.TopMost = SettingDialog.AlwaysTop;
8819 if (!string.IsNullOrEmpty(tabName))
8822 ListElement list = null;
8823 if (tabUsage == MyCommon.TabUsageType.Lists)
8825 using (ListAvailable listAvail = new ListAvailable())
8827 if (listAvail.ShowDialog(this) == DialogResult.Cancel) return;
8828 if (listAvail.SelectedList == null) return;
8829 list = listAvail.SelectedList;
8832 if (!_statuses.AddTab(tabName, tabUsage, list) || !AddNewTab(tabName, false, tabUsage, list))
8834 string tmp = string.Format(Properties.Resources.AddTabMenuItem_ClickText1, tabName);
8835 MessageBox.Show(tmp, Properties.Resources.AddTabMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
8841 if (tabUsage == MyCommon.TabUsageType.PublicSearch)
8843 ListTab.SelectedIndex = ListTab.TabPages.Count - 1;
8844 ListTabSelect(ListTab.TabPages[ListTab.TabPages.Count - 1]);
8845 ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"].Focus();
8847 if (tabUsage == MyCommon.TabUsageType.Lists)
8849 ListTab.SelectedIndex = ListTab.TabPages.Count - 1;
8850 ListTabSelect(ListTab.TabPages[ListTab.TabPages.Count - 1]);
8851 GetTimeline(MyCommon.WORKERTYPE.List, 1, 0, tabName);
8857 private void TabMenuItem_Click(object sender, EventArgs e)
8860 foreach (int idx in _curList.SelectedIndices)
8864 if (!SelectTab(out tabName)) return;
8866 fltDialog.SetCurrent(tabName);
8867 if (_statuses[_curTab.Text, idx].RetweetedId == 0)
8869 fltDialog.AddNewFilter(_statuses[_curTab.Text, idx].ScreenName, _statuses[_curTab.Text, idx].TextFromApi);
8873 fltDialog.AddNewFilter(_statuses[_curTab.Text, idx].RetweetedBy, _statuses[_curTab.Text, idx].TextFromApi);
8875 fltDialog.ShowDialog(this);
8876 this.TopMost = SettingDialog.AlwaysTop;
8881 this.Cursor = Cursors.WaitCursor;
8886 _statuses.FilterAll();
8887 foreach (TabPage tb in ListTab.TabPages)
8889 ((DetailsListView)tb.Tag).VirtualListSize = _statuses.Tabs[tb.Text].AllCount;
8890 if (_statuses.Tabs[tb.Text].UnreadCount > 0)
8892 if (SettingDialog.TabIconDisp)
8897 if (SettingDialog.TabIconDisp)
8901 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
8905 this.Cursor = Cursors.Default;
8908 if (this.ListTab.SelectedTab != null &&
8909 ((DetailsListView)this.ListTab.SelectedTab.Tag).SelectedIndices.Count > 0)
8911 _curPost = _statuses[this.ListTab.SelectedTab.Text, ((DetailsListView)this.ListTab.SelectedTab.Tag).SelectedIndices[0]];
8915 protected override bool ProcessDialogKey(Keys keyData)
8917 //TextBox1でEnterを押してもビープ音が鳴らないようにする
8918 if ((keyData & Keys.KeyCode) == Keys.Enter)
8920 if (StatusText.Focused)
8922 bool _NewLine = false;
8925 if (SettingDialog.PostCtrlEnter) //Ctrl+Enter投稿時
8927 if (StatusText.Multiline)
8929 if ((keyData & Keys.Shift) == Keys.Shift && (keyData & Keys.Control) != Keys.Control) _NewLine = true;
8931 if ((keyData & Keys.Control) == Keys.Control) _Post = true;
8935 if (((keyData & Keys.Control) == Keys.Control)) _Post = true;
8939 else if (SettingDialog.PostShiftEnter) //SHift+Enter投稿時
8941 if (StatusText.Multiline)
8943 if ((keyData & Keys.Control) == Keys.Control && (keyData & Keys.Shift) != Keys.Shift) _NewLine = true;
8945 if ((keyData & Keys.Shift) == Keys.Shift) _Post = true;
8949 if (((keyData & Keys.Shift) == Keys.Shift)) _Post = true;
8955 if (StatusText.Multiline)
8957 if ((keyData & Keys.Shift) == Keys.Shift && (keyData & Keys.Control) != Keys.Control) _NewLine = true;
8959 if (((keyData & Keys.Control) != Keys.Control && (keyData & Keys.Shift) != Keys.Shift) ||
8960 ((keyData & Keys.Control) == Keys.Control && (keyData & Keys.Shift) == Keys.Shift)) _Post = true;
8964 if (((keyData & Keys.Shift) == Keys.Shift) ||
8965 (((keyData & Keys.Control) != Keys.Control) &&
8966 ((keyData & Keys.Shift) != Keys.Shift))) _Post = true;
8972 int pos1 = StatusText.SelectionStart;
8973 if (StatusText.SelectionLength > 0)
8975 StatusText.Text = StatusText.Text.Remove(pos1, StatusText.SelectionLength); //選択状態文字列削除
8977 StatusText.Text = StatusText.Text.Insert(pos1, Environment.NewLine); //改行挿入
8978 StatusText.SelectionStart = pos1 + Environment.NewLine.Length; //カーソルを改行の次の文字へ移動
8983 PostButton_Click(null, null);
8987 else if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.PublicSearch &&
8988 (ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"].Focused ||
8989 ListTab.SelectedTab.Controls["panelSearch"].Controls["comboLang"].Focused))
8991 this.SearchButton_Click(ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"], null);
8996 return base.ProcessDialogKey(keyData);
8999 private void ReplyAllStripMenuItem_Click(object sender, EventArgs e)
9001 MakeReplyOrDirectStatus(false, true, true);
9004 private void IDRuleMenuItem_Click(object sender, EventArgs e)
9009 if (_curList.SelectedIndices.Count == 0) return;
9012 if (!SelectTab(out tabName)) return;
9016 MoveOrCopy(ref mv, ref mk);
9018 List<string> ids = new List<string>();
9019 foreach (int idx in _curList.SelectedIndices)
9021 PostClass post = _statuses[_curTab.Text, idx];
9022 if (!ids.Contains(post.ScreenName))
9024 FiltersClass fc = new FiltersClass();
9025 ids.Add(post.ScreenName);
9026 if (post.RetweetedId == 0)
9028 fc.NameFilter = post.ScreenName;
9032 fc.NameFilter = post.RetweetedBy;
9034 fc.SearchBoth = true;
9037 fc.UseRegex = false;
9038 fc.SearchUrl = false;
9039 _statuses.Tabs[tabName].AddFilter(fc);
9044 List<string> atids = new List<string>();
9045 foreach (string id in ids)
9047 atids.Add("@" + id);
9049 int cnt = AtIdSupl.ItemCount;
9050 AtIdSupl.AddRangeItem(atids.ToArray());
9051 if (AtIdSupl.ItemCount != cnt) _modifySettingAtId = true;
9056 this.Cursor = Cursors.WaitCursor;
9061 _statuses.FilterAll();
9062 foreach (TabPage tb in ListTab.TabPages)
9064 ((DetailsListView)tb.Tag).VirtualListSize = _statuses.Tabs[tb.Text].AllCount;
9065 if (_statuses.ContainsTab(tb.Text))
9067 if (_statuses.Tabs[tb.Text].UnreadCount > 0)
9069 if (SettingDialog.TabIconDisp)
9074 if (SettingDialog.TabIconDisp)
9079 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
9083 this.Cursor = Cursors.Default;
9088 private bool SelectTab(out string tabName)
9095 using (var dialog = new TabsDialog(_statuses))
9097 if (dialog.ShowDialog(this) == DialogResult.Cancel) return false;
9099 var selectedTab = dialog.SelectedTab;
9100 tabName = selectedTab == null ? null : selectedTab.TabName;
9103 ListTab.SelectedTab.Focus();
9105 if (tabName == null)
9107 using (InputTabName inputName = new InputTabName())
9109 inputName.TabName = _statuses.GetUniqueTabName();
9110 inputName.ShowDialog();
9111 if (inputName.DialogResult == DialogResult.Cancel) return false;
9112 tabName = inputName.TabName;
9114 this.TopMost = SettingDialog.AlwaysTop;
9115 if (!string.IsNullOrEmpty(tabName))
9117 if (!_statuses.AddTab(tabName, MyCommon.TabUsageType.UserDefined, null) || !AddNewTab(tabName, false, MyCommon.TabUsageType.UserDefined))
9119 string tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText2, tabName);
9120 MessageBox.Show(tmp, Properties.Resources.IDRuleMenuItem_ClickText3, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
9138 private void MoveOrCopy(ref bool move, ref bool mark)
9142 string _tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText4, Environment.NewLine);
9143 if (MessageBox.Show(_tmp, Properties.Resources.IDRuleMenuItem_ClickText5, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
9151 string _tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText6, Environment.NewLine);
9152 if (MessageBox.Show(_tmp, Properties.Resources.IDRuleMenuItem_ClickText7, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
9158 private void CopySTOTMenuItem_Click(object sender, EventArgs e)
9163 private void CopyURLMenuItem_Click(object sender, EventArgs e)
9168 private void SelectAllMenuItem_Click(object sender, EventArgs e)
9170 if (StatusText.Focused)
9173 StatusText.SelectAll();
9177 // ListView上でのCtrl+A
9178 for (int i = 0; i < _curList.VirtualListSize; i++)
9180 _curList.SelectedIndices.Add(i);
9185 private void MoveMiddle()
9191 if (_curList.SelectedIndices.Count == 0) return;
9193 int idx = _curList.SelectedIndices[0];
9195 _item = _curList.GetItemAt(0, 25);
9201 _item = _curList.GetItemAt(0, _curList.ClientSize.Height - 1);
9203 idx2 = _curList.VirtualListSize - 1;
9207 idx -= Math.Abs(idx1 - idx2) / 2;
9208 if (idx < 0) idx = 0;
9210 _curList.EnsureVisible(_curList.VirtualListSize - 1);
9211 _curList.EnsureVisible(idx);
9214 private void OpenURLMenuItem_Click(object sender, EventArgs e)
9216 if (PostBrowser.Document.Links.Count > 0)
9218 UrlDialog.ClearUrl();
9220 string openUrlStr = "";
9222 if (PostBrowser.Document.Links.Count == 1)
9227 urlStr = MyCommon.IDNDecode(PostBrowser.Document.Links[0].GetAttribute("href"));
9229 catch (ArgumentException)
9238 if (string.IsNullOrEmpty(urlStr)) return;
9239 openUrlStr = MyCommon.urlEncodeMultibyteChar(urlStr);
9243 foreach (HtmlElement linkElm in PostBrowser.Document.Links)
9246 string linkText = "";
9250 urlStr = linkElm.GetAttribute("title");
9251 href = MyCommon.IDNDecode(linkElm.GetAttribute("href"));
9252 if (string.IsNullOrEmpty(urlStr)) urlStr = href;
9253 linkText = linkElm.InnerText;
9254 if (!linkText.StartsWith("http") && !linkText.StartsWith("#") && !linkText.Contains("."))
9256 linkText = "@" + linkText;
9259 catch (ArgumentException)
9268 if (string.IsNullOrEmpty(urlStr)) continue;
9269 UrlDialog.AddUrl(new OpenUrlItem(linkText, MyCommon.urlEncodeMultibyteChar(urlStr), href));
9273 if (UrlDialog.ShowDialog() == DialogResult.OK)
9275 openUrlStr = UrlDialog.SelectedUrl;
9282 this.TopMost = SettingDialog.AlwaysTop;
9284 if (string.IsNullOrEmpty(openUrlStr)) return;
9286 if (openUrlStr.StartsWith("http://twitter.com/search?q=") ||
9287 openUrlStr.StartsWith("https://twitter.com/search?q="))
9290 string urlStr = HttpUtility.UrlDecode(openUrlStr);
9291 string hash = urlStr.Substring(urlStr.IndexOf("#"));
9292 HashSupl.AddItem(hash);
9293 HashMgr.AddHashToHistory(hash.Trim(), false);
9294 AddNewTabForSearch(hash);
9299 Match m = Regex.Match(openUrlStr, "^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)$");
9300 if (SettingDialog.OpenUserTimeline && m.Success && IsTwitterId(m.Result("${ScreenName}")))
9301 this.AddNewTabForUserTimeline(m.Result("${ScreenName}"));
9303 OpenUriAsync(openUrlStr);
9309 private void ClearTabMenuItem_Click(object sender, EventArgs e)
9311 if (string.IsNullOrEmpty(_rclickTabName)) return;
9312 ClearTab(_rclickTabName, true);
9315 private void ClearTab(string tabName, bool showWarning)
9319 string tmp = string.Format(Properties.Resources.ClearTabMenuItem_ClickText1, Environment.NewLine);
9320 if (MessageBox.Show(tmp, tabName + " " + Properties.Resources.ClearTabMenuItem_ClickText2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
9326 _statuses.ClearTabIds(tabName);
9327 if (ListTab.SelectedTab.Text == tabName)
9330 _anchorFlag = false;
9333 _itemCacheIndex = -1;
9337 foreach (TabPage tb in ListTab.TabPages)
9339 if (tb.Text == tabName)
9342 ((DetailsListView)tb.Tag).VirtualListSize = 0;
9346 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
9348 SetMainWindowTitle();
9349 SetStatusLabelUrl();
9352 private static long followers = 0;
9354 private void SetMainWindowTitle()
9357 StringBuilder ttl = new StringBuilder(256);
9360 if (SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.None &&
9361 SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.Post &&
9362 SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.Ver &&
9363 SettingDialog.DispLatestPost != MyCommon.DispTitleEnum.OwnStatus)
9365 foreach (string key in _statuses.Tabs.Keys)
9367 ur += _statuses.Tabs[key].UnreadCount;
9368 al += _statuses.Tabs[key].AllCount;
9372 if (SettingDialog.DispUsername) ttl.Append(tw.Username).Append(" - ");
9373 ttl.Append(Application.ProductName);
9375 switch (SettingDialog.DispLatestPost)
9377 case MyCommon.DispTitleEnum.Ver:
9378 ttl.Append("Ver:").Append(MyCommon.GetReadableVersion());
9380 case MyCommon.DispTitleEnum.Post:
9381 if (_history != null && _history.Count > 1)
9382 ttl.Append(_history[_history.Count - 2].status.Replace("\r\n", " "));
9384 case MyCommon.DispTitleEnum.UnreadRepCount:
9385 ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText1, _statuses.GetTabByType(MyCommon.TabUsageType.Mentions).UnreadCount + _statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage).UnreadCount);
9387 case MyCommon.DispTitleEnum.UnreadAllCount:
9388 ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText2, ur);
9390 case MyCommon.DispTitleEnum.UnreadAllRepCount:
9391 ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText3, ur, _statuses.GetTabByType(MyCommon.TabUsageType.Mentions).UnreadCount + _statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage).UnreadCount);
9393 case MyCommon.DispTitleEnum.UnreadCountAllCount:
9394 ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText4, ur, al);
9396 case MyCommon.DispTitleEnum.OwnStatus:
9397 if (followers == 0 && tw.FollowersCount > 0) followers = tw.FollowersCount;
9398 ttl.AppendFormat(Properties.Resources.OwnStatusTitle, tw.StatusesCount, tw.FriendsCount, tw.FollowersCount, tw.FollowersCount - followers);
9404 this.Text = ttl.ToString();
9406 catch (AccessViolationException)
9408 //原因不明。ポスト内容に依存か?たまーに発生するが再現せず。
9412 private string GetStatusLabelText()
9415 //タブ未読数/タブ発言数 全未読数/総発言数 (未読@+未読DM数)
9416 if (_statuses == null) return "";
9417 TabClass tbRep = _statuses.GetTabByType(MyCommon.TabUsageType.Mentions);
9418 TabClass tbDm = _statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage);
9419 if (tbRep == null || tbDm == null) return "";
9420 int urat = tbRep.UnreadCount + tbDm.UnreadCount;
9425 StringBuilder slbl = new StringBuilder(256);
9428 foreach (string key in _statuses.Tabs.Keys)
9430 ur += _statuses.Tabs[key].UnreadCount;
9431 al += _statuses.Tabs[key].AllCount;
9432 if (key.Equals(_curTab.Text))
9434 tur = _statuses.Tabs[key].UnreadCount;
9435 tal = _statuses.Tabs[key].AllCount;
9445 UnreadAtCounter = urat;
9447 slbl.AppendFormat(Properties.Resources.SetStatusLabelText1, tur, tal, ur, al, urat, _postTimestamps.Count, _favTimestamps.Count, _tlCount);
9448 if (SettingDialog.TimelinePeriodInt == 0)
9450 slbl.Append(Properties.Resources.SetStatusLabelText2);
9454 slbl.Append(SettingDialog.TimelinePeriodInt.ToString() + Properties.Resources.SetStatusLabelText3);
9456 return slbl.ToString();
9459 delegate void SetStatusLabelApiDelegate();
9461 private void SetStatusLabelApiHandler(object sender, ApiInformationChangedEventArgs e)
9465 if (InvokeRequired && !IsDisposed)
9467 Invoke(new SetStatusLabelApiDelegate(SetStatusLabelApi));
9471 SetStatusLabelApi();
9474 catch (ObjectDisposedException)
9478 catch (InvalidOperationException)
9484 private void SetStatusLabelApi()
9486 this._apiGauge.RemainCount = MyCommon.TwitterApiInfo.RemainCount;
9487 this._apiGauge.MaxCount = MyCommon.TwitterApiInfo.MaxCount;
9488 this._apiGauge.ResetTime = MyCommon.TwitterApiInfo.ResetTime;
9491 private void SetStatusLabelUrl()
9493 StatusLabelUrl.Text = GetStatusLabelText();
9496 public void SetStatusLabel(string text)
9498 StatusLabel.Text = text;
9501 private static StringBuilder ur = new StringBuilder(64);
9503 private void SetNotifyIconText()
9505 // タスクトレイアイコンのツールチップテキスト書き換え
9507 ur.Remove(0, ur.Length);
9508 if (SettingDialog.DispUsername)
9510 ur.Append(tw.Username);
9513 ur.Append(Application.ProductName);
9515 ur.Append("(Debug Build)");
9517 if (UnreadCounter != -1 && UnreadAtCounter != -1)
9520 ur.Append(UnreadCounter);
9522 ur.Append(UnreadAtCounter);
9525 NotifyIcon1.Text = ur.ToString();
9528 internal void CheckReplyTo(string StatusText)
9532 m = Regex.Matches(StatusText, Twitter.HASHTAG, RegexOptions.IgnoreCase);
9534 foreach (Match hm in m)
9536 if (!hstr.Contains("#" + hm.Result("$3") + " "))
9538 hstr += "#" + hm.Result("$3") + " ";
9539 HashSupl.AddItem("#" + hm.Result("$3"));
9542 if (!string.IsNullOrEmpty(HashMgr.UseHash) && !hstr.Contains(HashMgr.UseHash + " "))
9544 hstr += HashMgr.UseHash;
9546 if (!string.IsNullOrEmpty(hstr)) HashMgr.AddHashToHistory(hstr.Trim(), false);
9548 // 本当にリプライ先指定すべきかどうかの判定
9549 m = Regex.Matches(StatusText, "(^|[ -/:-@[-^`{-~])(?<id>@[a-zA-Z0-9_]+)");
9551 if (SettingDialog.UseAtIdSupplement)
9553 int bCnt = AtIdSupl.ItemCount;
9554 foreach (Match mid in m)
9556 AtIdSupl.AddItem(mid.Result("${id}"));
9558 if (bCnt != AtIdSupl.ItemCount) _modifySettingAtId = true;
9561 // リプライ先ステータスIDの指定がない場合は指定しない
9562 if (_reply_to_id == 0) return;
9564 // リプライ先ユーザー名がない場合も指定しない
9565 if (string.IsNullOrEmpty(_reply_to_name))
9572 // 次の条件を満たす場合に in_reply_to_status_id 指定
9573 // 1. Twitterによりリンクと判定される @idが文中に1つ含まれる (2009/5/28 リンク化される@IDのみカウントするように修正)
9574 // 2. リプライ先ステータスIDが設定されている(リストをダブルクリックで返信している)
9575 // 3. 文中に含まれた@idがリプライ先のポスト者のIDと一致する
9579 if (StatusText.StartsWith("@"))
9581 if (StatusText.StartsWith("@" + _reply_to_name)) return;
9585 foreach (Match mid in m)
9587 if (StatusText.Contains("QT " + mid.Result("${id}") + ":") && mid.Result("${id}") == "@" + _reply_to_name) return;
9593 _reply_to_name = "";
9597 private void TweenMain_Resize(object sender, EventArgs e)
9599 if (!_initialLayout && SettingDialog.MinimizeToTray && WindowState == FormWindowState.Minimized)
9601 this.Visible = false;
9603 if (_initialLayout && _cfgLocal != null && this.WindowState == FormWindowState.Normal && this.Visible)
9605 this.ClientSize = _cfgLocal.FormSize;
9606 //_mySize = this.ClientSize; //サイズ保持(最小化・最大化されたまま終了した場合の対応用)
9607 this.DesktopLocation = _cfgLocal.FormLocation;
9608 //_myLoc = this.DesktopLocation; //位置保持(最小化・最大化されたまま終了した場合の対応用)
9609 //if (_cfgLocal.AdSplitterDistance > this.SplitContainer4.Panel1MinSize &&
9610 // _cfgLocal.AdSplitterDistance < this.SplitContainer4.Height - this.SplitContainer4.Panel2MinSize - this.SplitContainer4.SplitterWidth)
9612 // this.SplitContainer4.SplitterDistance = _cfgLocal.AdSplitterDistance; //Splitterの位置設定
9614 if (_cfgLocal.SplitterDistance > this.SplitContainer1.Panel1MinSize &&
9615 _cfgLocal.SplitterDistance < this.SplitContainer1.Height - this.SplitContainer1.Panel2MinSize - this.SplitContainer1.SplitterWidth)
9617 this.SplitContainer1.SplitterDistance = _cfgLocal.SplitterDistance; //Splitterの位置設定
9620 StatusText.Multiline = _cfgLocal.StatusMultiline;
9621 if (StatusText.Multiline)
9623 int dis = SplitContainer2.Height - _cfgLocal.StatusTextHeight - SplitContainer2.SplitterWidth;
9624 if (dis > SplitContainer2.Panel1MinSize && dis < SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth)
9626 SplitContainer2.SplitterDistance = SplitContainer2.Height - _cfgLocal.StatusTextHeight - SplitContainer2.SplitterWidth;
9628 StatusText.Height = _cfgLocal.StatusTextHeight;
9632 if (SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth > 0)
9634 SplitContainer2.SplitterDistance = SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth;
9637 if (_cfgLocal.PreviewDistance > this.SplitContainer3.Panel1MinSize && _cfgLocal.PreviewDistance < this.SplitContainer3.Width - this.SplitContainer3.Panel2MinSize - this.SplitContainer3.SplitterWidth)
9639 this.SplitContainer3.SplitterDistance = _cfgLocal.PreviewDistance;
9641 _initialLayout = false;
9643 if (this.WindowState != FormWindowState.Minimized)
9645 _formWindowState = this.WindowState;
9649 private void PlaySoundMenuItem_CheckedChanged(object sender, EventArgs e)
9651 PlaySoundMenuItem.Checked = ((ToolStripMenuItem)sender).Checked;
9652 this.PlaySoundFileMenuItem.Checked = PlaySoundMenuItem.Checked;
9653 if (PlaySoundMenuItem.Checked)
9655 SettingDialog.PlaySound = true;
9659 SettingDialog.PlaySound = false;
9661 _modifySettingCommon = true;
9664 private void SplitContainer1_SplitterMoved(object sender, SplitterEventArgs e)
9666 if (this.WindowState == FormWindowState.Normal && !_initialLayout)
9668 _mySpDis = SplitContainer1.SplitterDistance;
9669 if (StatusText.Multiline) _mySpDis2 = StatusText.Height;
9670 _modifySettingLocal = true;
9674 private void doRepliedStatusOpen()
9676 if (this.ExistCurrentPost && _curPost.InReplyToUser != null && _curPost.InReplyToStatusId > 0)
9678 if (MyCommon.IsKeyDown(Keys.Shift))
9680 OpenUriAsync(MyCommon.GetStatusUrl(_curPost.InReplyToUser, _curPost.InReplyToStatusId));
9683 if (_statuses.ContainsKey(_curPost.InReplyToStatusId))
9685 PostClass repPost = _statuses[_curPost.InReplyToStatusId];
9686 MessageBox.Show(repPost.ScreenName + " / " + repPost.Nickname + " (" + repPost.CreatedAt.ToString() + ")" + Environment.NewLine + repPost.TextFromApi);
9690 foreach (TabClass tb in _statuses.GetTabsByType(MyCommon.TabUsageType.Lists | MyCommon.TabUsageType.PublicSearch))
9692 if (tb == null || !tb.Contains(_curPost.InReplyToStatusId)) break;
9693 PostClass repPost = _statuses[_curPost.InReplyToStatusId];
9694 MessageBox.Show(repPost.ScreenName + " / " + repPost.Nickname + " (" + repPost.CreatedAt.ToString() + ")" + Environment.NewLine + repPost.TextFromApi);
9697 OpenUriAsync(MyCommon.GetStatusUrl(_curPost.InReplyToUser, _curPost.InReplyToStatusId));
9702 private void RepliedStatusOpenMenuItem_Click(object sender, EventArgs e)
9704 doRepliedStatusOpen();
9707 private void ContextMenuUserPicture_Opening(object sender, CancelEventArgs e)
9709 //発言詳細のアイコン右クリック時のメニュー制御
9710 if (_curList.SelectedIndices.Count > 0 && _curPost != null)
9712 string name = _curPost.ImageUrl;
9713 if (name != null && name.Length > 0)
9715 int idx = name.LastIndexOf('/');
9718 name = Path.GetFileName(name.Substring(idx));
9719 if (name.Contains("_normal.") || name.EndsWith("_normal"))
9721 name = name.Replace("_normal", "");
9722 this.IconNameToolStripMenuItem.Text = name;
9723 this.IconNameToolStripMenuItem.Enabled = true;
9727 this.IconNameToolStripMenuItem.Enabled = false;
9728 this.IconNameToolStripMenuItem.Text = Properties.Resources.ContextMenuStrip3_OpeningText1;
9733 this.IconNameToolStripMenuItem.Enabled = false;
9734 this.IconNameToolStripMenuItem.Text = Properties.Resources.ContextMenuStrip3_OpeningText1;
9736 if (this.TIconDic[_curPost.ImageUrl] != null)
9738 this.SaveIconPictureToolStripMenuItem.Enabled = true;
9742 this.SaveIconPictureToolStripMenuItem.Enabled = false;
9747 this.IconNameToolStripMenuItem.Enabled = false;
9748 this.SaveIconPictureToolStripMenuItem.Enabled = false;
9749 this.IconNameToolStripMenuItem.Text = Properties.Resources.ContextMenuStrip3_OpeningText1;
9754 this.IconNameToolStripMenuItem.Enabled = false;
9755 this.SaveIconPictureToolStripMenuItem.Enabled = false;
9756 this.IconNameToolStripMenuItem.Text = Properties.Resources.ContextMenuStrip3_OpeningText2;
9758 if (NameLabel.Tag != null)
9760 string id = (string)NameLabel.Tag;
9761 if (id == tw.Username)
9763 FollowToolStripMenuItem.Enabled = false;
9764 UnFollowToolStripMenuItem.Enabled = false;
9765 ShowFriendShipToolStripMenuItem.Enabled = false;
9766 ShowUserStatusToolStripMenuItem.Enabled = true;
9767 SearchPostsDetailNameToolStripMenuItem.Enabled = true;
9768 SearchAtPostsDetailNameToolStripMenuItem.Enabled = false;
9769 ListManageUserContextToolStripMenuItem3.Enabled = true;
9773 FollowToolStripMenuItem.Enabled = true;
9774 UnFollowToolStripMenuItem.Enabled = true;
9775 ShowFriendShipToolStripMenuItem.Enabled = true;
9776 ShowUserStatusToolStripMenuItem.Enabled = true;
9777 SearchPostsDetailNameToolStripMenuItem.Enabled = true;
9778 SearchAtPostsDetailNameToolStripMenuItem.Enabled = true;
9779 ListManageUserContextToolStripMenuItem3.Enabled = true;
9784 FollowToolStripMenuItem.Enabled = false;
9785 UnFollowToolStripMenuItem.Enabled = false;
9786 ShowFriendShipToolStripMenuItem.Enabled = false;
9787 ShowUserStatusToolStripMenuItem.Enabled = false;
9788 SearchPostsDetailNameToolStripMenuItem.Enabled = false;
9789 SearchAtPostsDetailNameToolStripMenuItem.Enabled = false;
9790 ListManageUserContextToolStripMenuItem3.Enabled = false;
9794 private void IconNameToolStripMenuItem_Click(object sender, EventArgs e)
9796 if (_curPost == null) return;
9797 string name = _curPost.ImageUrl;
9798 OpenUriAsync(name.Remove(name.LastIndexOf("_normal"), 7)); // "_normal".Length
9801 private void SaveOriginalSizeIconPictureToolStripMenuItem_Click(object sender, EventArgs e)
9803 if (_curPost == null) return;
9804 string name = _curPost.ImageUrl;
9805 name = Path.GetFileNameWithoutExtension(name.Substring(name.LastIndexOf('/')));
9807 this.SaveFileDialog1.FileName = name.Substring(0, name.Length - 8); // "_normal".Length + 1
9809 if (this.SaveFileDialog1.ShowDialog() == DialogResult.OK)
9815 private void SaveIconPictureToolStripMenuItem_Click(object sender, EventArgs e)
9817 if (_curPost == null) return;
9818 string name = _curPost.ImageUrl;
9820 this.SaveFileDialog1.FileName = name.Substring(name.LastIndexOf('/') + 1);
9822 if (this.SaveFileDialog1.ShowDialog() == DialogResult.OK)
9826 using (Image orgBmp = new Bitmap(TIconDic[name]))
9828 using (Bitmap bmp2 = new Bitmap(orgBmp.Size.Width, orgBmp.Size.Height))
9830 using (Graphics g = Graphics.FromImage(bmp2))
9832 g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
9833 g.DrawImage(orgBmp, 0, 0, orgBmp.Size.Width, orgBmp.Size.Height);
9835 bmp2.Save(this.SaveFileDialog1.FileName);
9841 //処理中にキャッシュアウトする可能性あり
9846 private void SplitContainer2_Panel2_Resize(object sender, EventArgs e)
9848 this.StatusText.Multiline = this.SplitContainer2.Panel2.Height > this.SplitContainer2.Panel2MinSize + 2;
9849 MultiLineMenuItem.Checked = this.StatusText.Multiline;
9850 _modifySettingLocal = true;
9853 private void StatusText_MultilineChanged(object sender, EventArgs e)
9855 if (this.StatusText.Multiline)
9856 this.StatusText.ScrollBars = ScrollBars.Vertical;
9858 this.StatusText.ScrollBars = ScrollBars.None;
9860 _modifySettingLocal = true;
9863 private void MultiLineMenuItem_Click(object sender, EventArgs e)
9866 StatusText.Multiline = MultiLineMenuItem.Checked;
9867 _cfgLocal.StatusMultiline = MultiLineMenuItem.Checked;
9868 if (MultiLineMenuItem.Checked)
9870 if (SplitContainer2.Height - _mySpDis2 - SplitContainer2.SplitterWidth < 0)
9871 SplitContainer2.SplitterDistance = 0;
9873 SplitContainer2.SplitterDistance = SplitContainer2.Height - _mySpDis2 - SplitContainer2.SplitterWidth;
9877 SplitContainer2.SplitterDistance = SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth;
9879 _modifySettingLocal = true;
9882 private bool UrlConvert(MyCommon.UrlConverter Converter_Type)
9884 //t.coで投稿時自動短縮する場合は、外部サービスでの短縮禁止
9885 //if (SettingDialog.UrlConvertAuto && SettingDialog.ShortenTco) return;
9887 //Converter_Type=Nicomsの場合は、nicovideoのみ短縮する
9888 //参考資料 RFC3986 Uniform Resource Identifier (URI): Generic Syntax
9889 //Appendix A. Collected ABNF for URI
9890 //http://www.ietf.org/rfc/rfc3986.txt
9894 const string nico = @"^https?://[a-z]+\.(nicovideo|niconicommons|nicolive)\.jp/[a-z]+/[a-z0-9]+$";
9896 if (StatusText.SelectionLength > 0)
9898 string tmp = StatusText.SelectedText;
9899 // httpから始まらない場合、ExcludeStringで指定された文字列で始まる場合は対象としない
9900 if (tmp.StartsWith("http"))
9902 // 文字列が選択されている場合はその文字列について処理
9904 //nico.ms使用、nicovideoにマッチしたら変換
9905 if (SettingDialog.Nicoms && Regex.IsMatch(tmp, nico))
9907 result = nicoms.Shorten(tmp);
9909 else if (Converter_Type != MyCommon.UrlConverter.Nicoms)
9911 //短縮URL変換 日本語を含むかもしれないのでURLエンコードする
9912 result = ShortUrl.Make(Converter_Type, tmp);
9913 if (result.Equals("Can't convert"))
9915 StatusLabel.Text = result.Insert(0, Converter_Type.ToString() + ":");
9924 if (!string.IsNullOrEmpty(result))
9926 urlUndo undotmp = new urlUndo();
9928 StatusText.Select(StatusText.Text.IndexOf(tmp, StringComparison.Ordinal), tmp.Length);
9929 StatusText.SelectedText = result;
9932 undotmp.Before = tmp;
9933 undotmp.After = result;
9935 if (urlUndoBuffer == null)
9937 urlUndoBuffer = new List<urlUndo>();
9938 UrlUndoToolStripMenuItem.Enabled = true;
9941 urlUndoBuffer.Add(undotmp);
9947 const string url = @"(?<before>(?:[^\""':!=]|^|\:))" +
9948 @"(?<url>(?<protocol>https?://)" +
9949 @"(?<domain>(?:[\.-]|[^\p{P}\s])+\.[a-z]{2,}(?::[0-9]+)?)" +
9950 @"(?<path>/[a-z0-9!*//();:&=+$/%#\-_.,~@]*[a-z0-9)=#/]?)?" +
9951 @"(?<query>\?[a-z0-9!*//();:&=+$/%#\-_.,~@?]*[a-z0-9_&=#/])?)";
9952 // 正規表現にマッチしたURL文字列をtinyurl化
9953 foreach (Match mt in Regex.Matches(StatusText.Text, url, RegexOptions.IgnoreCase))
9955 if (StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal) == -1) continue;
9956 string tmp = mt.Result("${url}");
9957 if (tmp.StartsWith("w", StringComparison.OrdinalIgnoreCase)) tmp = "http://" + tmp;
9958 urlUndo undotmp = new urlUndo();
9961 StatusText.Select(StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length);
9963 //nico.ms使用、nicovideoにマッチしたら変換
9964 if (SettingDialog.Nicoms && Regex.IsMatch(tmp, nico))
9966 result = nicoms.Shorten(tmp);
9968 else if (Converter_Type != MyCommon.UrlConverter.Nicoms)
9970 //短縮URL変換 日本語を含むかもしれないのでURLエンコードする
9971 result = ShortUrl.Make(Converter_Type, tmp);
9972 if (result.Equals("Can't convert"))
9974 StatusLabel.Text = result.Insert(0, Converter_Type.ToString() + ":");
9983 if (!string.IsNullOrEmpty(result))
9985 StatusText.Select(StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length);
9986 StatusText.SelectedText = result;
9988 undotmp.Before = mt.Result("${url}");
9989 undotmp.After = result;
9991 if (urlUndoBuffer == null)
9993 urlUndoBuffer = new List<urlUndo>();
9994 UrlUndoToolStripMenuItem.Enabled = true;
9997 urlUndoBuffer.Add(undotmp);
10005 private void doUrlUndo()
10007 if (urlUndoBuffer != null)
10009 string tmp = StatusText.Text;
10010 foreach (urlUndo data in urlUndoBuffer)
10012 tmp = tmp.Replace(data.After, data.Before);
10014 StatusText.Text = tmp;
10015 urlUndoBuffer = null;
10016 UrlUndoToolStripMenuItem.Enabled = false;
10017 StatusText.SelectionStart = 0;
10018 StatusText.SelectionLength = 0;
10022 private void TinyURLToolStripMenuItem_Click(object sender, EventArgs e)
10024 UrlConvert(MyCommon.UrlConverter.TinyUrl);
10027 private void IsgdToolStripMenuItem_Click(object sender, EventArgs e)
10029 UrlConvert(MyCommon.UrlConverter.Isgd);
10032 private void TwurlnlToolStripMenuItem_Click(object sender, EventArgs e)
10034 UrlConvert(MyCommon.UrlConverter.Twurl);
10037 private void UxnuMenuItem_Click(object sender, EventArgs e)
10039 UrlConvert(MyCommon.UrlConverter.Uxnu);
10042 private void UrlConvertAutoToolStripMenuItem_Click(object sender, EventArgs e)
10044 if (!UrlConvert(SettingDialog.AutoShortUrlFirst))
10046 MyCommon.UrlConverter svc = SettingDialog.AutoShortUrlFirst;
10047 Random rnd = new Random();
10048 // 前回使用した短縮URLサービス以外を選択する
10051 svc = (MyCommon.UrlConverter)rnd.Next(System.Enum.GetNames(typeof(MyCommon.UrlConverter)).Length);
10053 while (svc == SettingDialog.AutoShortUrlFirst || svc == MyCommon.UrlConverter.Nicoms || svc == MyCommon.UrlConverter.Unu);
10058 private void UrlUndoToolStripMenuItem_Click(object sender, EventArgs e)
10063 private void NewPostPopMenuItem_CheckStateChanged(object sender, EventArgs e)
10065 this.NotifyFileMenuItem.Checked = ((ToolStripMenuItem)sender).Checked;
10066 this.NewPostPopMenuItem.Checked = this.NotifyFileMenuItem.Checked;
10067 _cfgCommon.NewAllPop = NewPostPopMenuItem.Checked;
10068 _modifySettingCommon = true;
10071 private void ListLockMenuItem_CheckStateChanged(object sender, EventArgs e)
10073 ListLockMenuItem.Checked = ((ToolStripMenuItem)sender).Checked;
10074 this.LockListFileMenuItem.Checked = ListLockMenuItem.Checked;
10075 _cfgCommon.ListLock = ListLockMenuItem.Checked;
10076 _modifySettingCommon = true;
10079 private void MenuStrip1_MenuActivate(object sender, EventArgs e)
10081 // フォーカスがメニューに移る (MenuStrip1.Tag フラグを立てる)
10082 MenuStrip1.Tag = new Object();
10083 MenuStrip1.Select(); // StatusText がフォーカスを持っている場合 Leave が発生
10086 private void MenuStrip1_MenuDeactivate(object sender, EventArgs e)
10088 if (this.Tag != null) // 設定された戻り先へ遷移
10090 if (this.Tag == this.ListTab.SelectedTab)
10091 ((Control)this.ListTab.SelectedTab.Tag).Select();
10093 ((Control)this.Tag).Select();
10095 else // 戻り先が指定されていない (初期状態) 場合はタブに遷移
10097 if (ListTab.SelectedIndex > -1 && ListTab.SelectedTab.HasChildren)
10099 this.Tag = ListTab.SelectedTab.Tag;
10100 ((Control)this.Tag).Select();
10103 // フォーカスがメニューに遷移したかどうかを表すフラグを降ろす
10104 MenuStrip1.Tag = null;
10107 private void MyList_ColumnReordered(object sender, ColumnReorderedEventArgs e)
10109 DetailsListView lst = (DetailsListView)sender;
10110 if (_cfgLocal == null) return;
10114 _cfgLocal.Width1 = lst.Columns[0].Width;
10115 _cfgLocal.Width3 = lst.Columns[1].Width;
10119 int[] darr = new int[lst.Columns.Count];
10120 for (int i = 0; i < lst.Columns.Count; i++)
10122 darr[lst.Columns[i].DisplayIndex] = i;
10124 MyCommon.MoveArrayItem(darr, e.OldDisplayIndex, e.NewDisplayIndex);
10126 for (int i = 0; i < lst.Columns.Count; i++)
10131 _cfgLocal.DisplayIndex1 = i;
10134 _cfgLocal.DisplayIndex2 = i;
10137 _cfgLocal.DisplayIndex3 = i;
10140 _cfgLocal.DisplayIndex4 = i;
10143 _cfgLocal.DisplayIndex5 = i;
10146 _cfgLocal.DisplayIndex6 = i;
10149 _cfgLocal.DisplayIndex7 = i;
10152 _cfgLocal.DisplayIndex8 = i;
10156 _cfgLocal.Width1 = lst.Columns[0].Width;
10157 _cfgLocal.Width2 = lst.Columns[1].Width;
10158 _cfgLocal.Width3 = lst.Columns[2].Width;
10159 _cfgLocal.Width4 = lst.Columns[3].Width;
10160 _cfgLocal.Width5 = lst.Columns[4].Width;
10161 _cfgLocal.Width6 = lst.Columns[5].Width;
10162 _cfgLocal.Width7 = lst.Columns[6].Width;
10163 _cfgLocal.Width8 = lst.Columns[7].Width;
10165 _modifySettingLocal = true;
10166 _isColumnChanged = true;
10169 private void MyList_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e)
10171 DetailsListView lst = (DetailsListView)sender;
10172 if (_cfgLocal == null) return;
10175 if (_cfgLocal.Width1 != lst.Columns[0].Width)
10177 _cfgLocal.Width1 = lst.Columns[0].Width;
10178 _modifySettingLocal = true;
10179 _isColumnChanged = true;
10181 if (_cfgLocal.Width3 != lst.Columns[1].Width)
10183 _cfgLocal.Width3 = lst.Columns[1].Width;
10184 _modifySettingLocal = true;
10185 _isColumnChanged = true;
10190 if (_cfgLocal.Width1 != lst.Columns[0].Width)
10192 _cfgLocal.Width1 = lst.Columns[0].Width;
10193 _modifySettingLocal = true;
10194 _isColumnChanged = true;
10196 if (_cfgLocal.Width2 != lst.Columns[1].Width)
10198 _cfgLocal.Width2 = lst.Columns[1].Width;
10199 _modifySettingLocal = true;
10200 _isColumnChanged = true;
10202 if (_cfgLocal.Width3 != lst.Columns[2].Width)
10204 _cfgLocal.Width3 = lst.Columns[2].Width;
10205 _modifySettingLocal = true;
10206 _isColumnChanged = true;
10208 if (_cfgLocal.Width4 != lst.Columns[3].Width)
10210 _cfgLocal.Width4 = lst.Columns[3].Width;
10211 _modifySettingLocal = true;
10212 _isColumnChanged = true;
10214 if (_cfgLocal.Width5 != lst.Columns[4].Width)
10216 _cfgLocal.Width5 = lst.Columns[4].Width;
10217 _modifySettingLocal = true;
10218 _isColumnChanged = true;
10220 if (_cfgLocal.Width6 != lst.Columns[5].Width)
10222 _cfgLocal.Width6 = lst.Columns[5].Width;
10223 _modifySettingLocal = true;
10224 _isColumnChanged = true;
10226 if (_cfgLocal.Width7 != lst.Columns[6].Width)
10228 _cfgLocal.Width7 = lst.Columns[6].Width;
10229 _modifySettingLocal = true;
10230 _isColumnChanged = true;
10232 if (_cfgLocal.Width8 != lst.Columns[7].Width)
10234 _cfgLocal.Width8 = lst.Columns[7].Width;
10235 _modifySettingLocal = true;
10236 _isColumnChanged = true;
10239 // 非表示の時にColumnChangedが呼ばれた場合はForm初期化処理中なので保存しない
10242 // SaveConfigsLocal();
10246 public string WebBrowser_GetSelectionText(ref WebBrowser ComponentInstance)
10248 //発言詳細で「選択文字列をコピー」を行う
10249 //WebBrowserコンポーネントのインスタンスを渡す
10250 Type typ = ComponentInstance.ActiveXInstance.GetType();
10251 object _SelObj = typ.InvokeMember("selection", BindingFlags.GetProperty, null, ComponentInstance.Document.DomDocument, null);
10252 object _objRange = _SelObj.GetType().InvokeMember("createRange", BindingFlags.InvokeMethod, null, _SelObj, null);
10253 return (string)_objRange.GetType().InvokeMember("text", BindingFlags.GetProperty, null, _objRange, null);
10256 private void SelectionCopyContextMenuItem_Click(object sender, EventArgs e)
10259 string _selText = WebBrowser_GetSelectionText(ref PostBrowser);
10262 Clipboard.SetDataObject(_selText, false, 5, 100);
10264 catch (Exception ex)
10266 MessageBox.Show(ex.Message);
10270 private void doSearchToolStrip(string url)
10272 //発言詳細で「選択文字列で検索」(選択文字列取得)
10273 string _selText = WebBrowser_GetSelectionText(ref PostBrowser);
10275 if (_selText != null)
10277 if (url == Properties.Resources.SearchItem4Url)
10280 AddNewTabForSearch(_selText);
10284 string tmp = string.Format(url, HttpUtility.UrlEncode(_selText));
10289 private void SelectionAllContextMenuItem_Click(object sender, EventArgs e)
10292 PostBrowser.Document.ExecCommand("SelectAll", false, null);
10295 private void SearchWikipediaContextMenuItem_Click(object sender, EventArgs e)
10297 doSearchToolStrip(Properties.Resources.SearchItem1Url);
10300 private void SearchGoogleContextMenuItem_Click(object sender, EventArgs e)
10302 doSearchToolStrip(Properties.Resources.SearchItem2Url);
10305 private void SearchPublicSearchContextMenuItem_Click(object sender, EventArgs e)
10307 doSearchToolStrip(Properties.Resources.SearchItem4Url);
10310 private void UrlCopyContextMenuItem_Click(object sender, EventArgs e)
10314 MatchCollection mc = Regex.Matches(this.PostBrowser.DocumentText, @"<a[^>]*href=""(?<url>" + this._postBrowserStatusText.Replace(".", @"\.") + @")""[^>]*title=""(?<title>https?://[^""]+)""", RegexOptions.IgnoreCase);
10315 foreach (Match m in mc)
10317 if (m.Groups["url"].Value == this._postBrowserStatusText)
10319 Clipboard.SetDataObject(m.Groups["title"].Value, false, 5, 100);
10325 Clipboard.SetDataObject(this._postBrowserStatusText, false, 5, 100);
10327 //Clipboard.SetDataObject(this._postBrowserStatusText, false, 5, 100);
10329 catch (Exception ex)
10331 MessageBox.Show(ex.Message);
10335 private void ContextMenuPostBrowser_Opening(object ender, CancelEventArgs e)
10337 // URLコピーの項目の表示/非表示
10338 if (PostBrowser.StatusText.StartsWith("http"))
10340 this._postBrowserStatusText = PostBrowser.StatusText;
10341 string name = GetUserId();
10342 UrlCopyContextMenuItem.Enabled = true;
10345 FollowContextMenuItem.Enabled = true;
10346 RemoveContextMenuItem.Enabled = true;
10347 FriendshipContextMenuItem.Enabled = true;
10348 ShowUserStatusContextMenuItem.Enabled = true;
10349 SearchPostsDetailToolStripMenuItem.Enabled = true;
10350 IdFilterAddMenuItem.Enabled = true;
10351 ListManageUserContextToolStripMenuItem.Enabled = true;
10352 SearchAtPostsDetailToolStripMenuItem.Enabled = true;
10356 FollowContextMenuItem.Enabled = false;
10357 RemoveContextMenuItem.Enabled = false;
10358 FriendshipContextMenuItem.Enabled = false;
10359 ShowUserStatusContextMenuItem.Enabled = false;
10360 SearchPostsDetailToolStripMenuItem.Enabled = false;
10361 IdFilterAddMenuItem.Enabled = false;
10362 ListManageUserContextToolStripMenuItem.Enabled = false;
10363 SearchAtPostsDetailToolStripMenuItem.Enabled = false;
10366 if (Regex.IsMatch(this._postBrowserStatusText, @"^https?://twitter.com/search\?q=%23"))
10367 UseHashtagMenuItem.Enabled = true;
10369 UseHashtagMenuItem.Enabled = false;
10373 this._postBrowserStatusText = "";
10374 UrlCopyContextMenuItem.Enabled = false;
10375 FollowContextMenuItem.Enabled = false;
10376 RemoveContextMenuItem.Enabled = false;
10377 FriendshipContextMenuItem.Enabled = false;
10378 ShowUserStatusContextMenuItem.Enabled = false;
10379 SearchPostsDetailToolStripMenuItem.Enabled = false;
10380 SearchAtPostsDetailToolStripMenuItem.Enabled = false;
10381 UseHashtagMenuItem.Enabled = false;
10382 IdFilterAddMenuItem.Enabled = false;
10383 ListManageUserContextToolStripMenuItem.Enabled = false;
10385 // 文字列選択されていないときは選択文字列関係の項目を非表示に
10386 string _selText = WebBrowser_GetSelectionText(ref PostBrowser);
10387 if (_selText == null)
10389 SelectionSearchContextMenuItem.Enabled = false;
10390 SelectionCopyContextMenuItem.Enabled = false;
10391 SelectionTranslationToolStripMenuItem.Enabled = false;
10395 SelectionSearchContextMenuItem.Enabled = true;
10396 SelectionCopyContextMenuItem.Enabled = true;
10397 SelectionTranslationToolStripMenuItem.Enabled = true;
10399 //発言内に自分以外のユーザーが含まれてればフォロー状態全表示を有効に
10400 MatchCollection ma = Regex.Matches(this.PostBrowser.DocumentText, @"href=""https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?""");
10401 bool fAllFlag = false;
10402 foreach (Match mu in ma)
10404 if (mu.Result("${ScreenName}").ToLower() != tw.Username.ToLower())
10410 this.FriendshipAllMenuItem.Enabled = fAllFlag;
10412 if (_curPost == null)
10413 TranslationToolStripMenuItem.Enabled = false;
10415 TranslationToolStripMenuItem.Enabled = true;
10420 private void CurrentTabToolStripMenuItem_Click(object sender, EventArgs e)
10422 //発言詳細の選択文字列で現在のタブを検索
10423 string _selText = WebBrowser_GetSelectionText(ref PostBrowser);
10425 if (_selText != null)
10427 SearchDialog.SWord = _selText;
10428 SearchDialog.CheckCaseSensitive = false;
10429 SearchDialog.CheckRegex = false;
10431 DoTabSearch(SearchDialog.SWord,
10432 SearchDialog.CheckCaseSensitive,
10433 SearchDialog.CheckRegex,
10434 SEARCHTYPE.NextSearch);
10438 private void SplitContainer2_SplitterMoved(object sender, SplitterEventArgs e)
10440 if (StatusText.Multiline) _mySpDis2 = StatusText.Height;
10441 _modifySettingLocal = true;
10444 private void TweenMain_DragDrop(object sender, DragEventArgs e)
10446 if (e.Data.GetDataPresent(DataFormats.FileDrop))
10448 ImageSelectionPanel.Visible = true;
10449 ImageSelectionPanel.Enabled = true;
10450 TimelinePanel.Visible = false;
10451 TimelinePanel.Enabled = false;
10452 ImagefilePathText.Text = ((string[])e.Data.GetData(DataFormats.FileDrop, false))[0];
10453 ImageFromSelectedFile();
10455 this.BringToFront();
10456 StatusText.Focus();
10458 else if (e.Data.GetDataPresent(DataFormats.StringFormat))
10460 string data = (string)e.Data.GetData(DataFormats.StringFormat, true);
10461 if (data != null) StatusText.Text += data;
10465 private void TweenMain_DragOver(object sender, DragEventArgs e)
10467 if (e.Data.GetDataPresent(DataFormats.FileDrop))
10469 string filename = ((string[])e.Data.GetData(DataFormats.FileDrop, false))[0];
10470 FileInfo fl = new FileInfo(filename);
10471 string ext = fl.Extension;
10473 if (!string.IsNullOrEmpty(this.ImageService) && this.pictureService[this.ImageService].CheckValidFilesize(ext, fl.Length))
10475 e.Effect = DragDropEffects.Copy;
10478 foreach (string svc in ImageServiceCombo.Items)
10480 if (string.IsNullOrEmpty(svc)) continue;
10481 if (this.pictureService[svc].CheckValidFilesize(ext, fl.Length))
10483 ImageServiceCombo.SelectedItem = svc;
10484 e.Effect = DragDropEffects.Copy;
10488 e.Effect = DragDropEffects.None;
10490 else if (e.Data.GetDataPresent(DataFormats.StringFormat))
10492 e.Effect = DragDropEffects.Copy;
10496 e.Effect = DragDropEffects.None;
10500 public bool IsNetworkAvailable()
10503 nw = MyCommon.IsNetworkAvailable();
10504 _myStatusOnline = nw;
10508 public void OpenUriAsync(string UriString)
10510 GetWorkerArg args = new GetWorkerArg();
10511 args.type = MyCommon.WORKERTYPE.OpenUri;
10512 args.url = UriString;
10517 private void ListTabSelect(TabPage _tab)
10522 _itemCacheIndex = -1;
10526 _curList = (DetailsListView)_tab.Tag;
10527 if (_curList.SelectedIndices.Count > 0)
10529 _curItemIndex = _curList.SelectedIndices[0];
10530 _curPost = GetCurTabPost(_curItemIndex);
10534 _curItemIndex = -1;
10538 _anchorPost = null;
10539 _anchorFlag = false;
10543 ((DetailsListView)_tab.Tag).Columns[1].Text = ColumnText[2];
10547 for (int i = 0; i < _curList.Columns.Count; i++)
10549 ((DetailsListView)_tab.Tag).Columns[i].Text = ColumnText[i];
10554 private void ListTab_Selecting(object sender, TabControlCancelEventArgs e)
10556 ListTabSelect(e.TabPage);
10559 private void SelectListItem(DetailsListView LView, int Index)
10562 Rectangle bnd = new Rectangle();
10564 if (LView.FocusedItem != null)
10566 bnd = LView.FocusedItem.Bounds;
10572 LView.SelectedIndices.Clear();
10574 while (LView.SelectedIndices.Count > 0);
10575 LView.Items[Index].Selected = true;
10576 //LView.SelectedIndices.Add(Index);
10577 LView.Items[Index].Focused = true;
10579 if (flg) LView.Invalidate(bnd);
10582 private void SelectListItem(DetailsListView LView , int[] Index, int FocusedIndex)
10585 Rectangle bnd = new Rectangle();
10587 if (LView.FocusedItem != null)
10589 bnd = LView.FocusedItem.Bounds;
10594 if (Index != null && !(Index.Length == 1 && Index[0] == -1))
10598 LView.SelectedIndices.Clear();
10600 while (LView.SelectedIndices.Count > 0);
10601 foreach (int idx in Index)
10603 if (idx > -1 && LView.VirtualListSize > idx)
10605 LView.SelectedIndices.Add(idx);
10606 if (fIdx == -1) fIdx = idx;
10610 if (FocusedIndex > -1 && LView.VirtualListSize > FocusedIndex)
10612 LView.Items[FocusedIndex].Focused = true;
10614 else if (fIdx > -1)
10616 LView.Items[fIdx].Focused = true;
10618 if (flg) LView.Invalidate(bnd);
10621 private void RunAsync(GetWorkerArg args)
10623 BackgroundWorker bw = null;
10624 if (args.type != MyCommon.WORKERTYPE.Follower)
10626 for (int i = 0; i < _bw.Length; i++)
10628 if (_bw[i] != null && !_bw[i].IsBusy)
10636 for (int i = 0; i < _bw.Length; i++)
10638 if (_bw[i] == null)
10640 _bw[i] = new BackgroundWorker();
10642 bw.WorkerReportsProgress = true;
10643 bw.WorkerSupportsCancellation = true;
10644 bw.DoWork += GetTimelineWorker_DoWork;
10645 bw.ProgressChanged += GetTimelineWorker_ProgressChanged;
10646 bw.RunWorkerCompleted += GetTimelineWorker_RunWorkerCompleted;
10654 if (_bwFollower == null)
10656 _bwFollower = new BackgroundWorker();
10658 bw.WorkerReportsProgress = true;
10659 bw.WorkerSupportsCancellation = true;
10660 bw.DoWork += GetTimelineWorker_DoWork;
10661 bw.ProgressChanged += GetTimelineWorker_ProgressChanged;
10662 bw.RunWorkerCompleted += GetTimelineWorker_RunWorkerCompleted;
10666 if (_bwFollower.IsBusy == false)
10670 if (bw == null) return;
10672 bw.RunWorkerAsync(args);
10675 private void StartUserStream()
10677 tw.NewPostFromStream += tw_NewPostFromStream;
10678 tw.UserStreamStarted += tw_UserStreamStarted;
10679 tw.UserStreamStopped += tw_UserStreamStopped;
10680 tw.PostDeleted += tw_PostDeleted;
10681 tw.UserStreamEventReceived += tw_UserStreamEventArrived;
10683 MenuItemUserStream.Text = "&UserStream ■";
10684 MenuItemUserStream.Enabled = true;
10685 StopToolStripMenuItem.Text = "&Start";
10686 StopToolStripMenuItem.Enabled = true;
10687 if (SettingDialog.UserstreamStartup) tw.StartUserStream();
10690 private void TweenMain_Shown(object sender, EventArgs e)
10694 PostBrowser.Url = new Uri("about:blank");
10695 PostBrowser.DocumentText = ""; //発言詳細部初期化
10701 NotifyIcon1.Visible = true;
10703 if (this.IsNetworkAvailable())
10705 GetTimeline(MyCommon.WORKERTYPE.BlockIds, 0, 0, "");
10706 if (SettingDialog.StartupFollowers)
10708 GetTimeline(MyCommon.WORKERTYPE.Follower, 0, 0, "");
10710 GetTimeline(MyCommon.WORKERTYPE.Configuration, 0, 0, "");
10712 _waitTimeline = true;
10713 GetTimeline(MyCommon.WORKERTYPE.Timeline, 1, 1, "");
10715 GetTimeline(MyCommon.WORKERTYPE.Reply, 1, 1, "");
10717 GetTimeline(MyCommon.WORKERTYPE.DirectMessegeRcv, 1, 1, "");
10718 if (SettingDialog.GetFav)
10721 GetTimeline(MyCommon.WORKERTYPE.Favorites, 1, 1, "");
10723 _waitPubSearch = true;
10724 GetTimeline(MyCommon.WORKERTYPE.PublicSearch, 1, 0, ""); //tabname="":全タブ
10725 _waitUserTimeline = true;
10726 GetTimeline(MyCommon.WORKERTYPE.UserTimeline, 1, 0, ""); //tabname="":全タブ
10728 GetTimeline(MyCommon.WORKERTYPE.List, 1, 0, ""); //tabname="":全タブ
10731 while (IsInitialRead() && !MyCommon._endingFlag)
10733 System.Threading.Thread.Sleep(100);
10734 Application.DoEvents();
10737 if (j > 1200) break; // 120秒間初期処理が終了しなかったら強制的に打ち切る
10740 if (MyCommon._endingFlag)
10746 if (MyCommon._endingFlag) return;
10748 //バージョンチェック(引数:起動時チェックの場合はtrue・・・チェック結果のメッセージを表示しない)
10749 if (SettingDialog.StartupVersion)
10750 CheckNewVersion(true);
10753 if (!tw.GetFollowersSuccess && SettingDialog.StartupFollowers)
10754 GetTimeline(MyCommon.WORKERTYPE.Follower, 0, 0, "");
10757 if (SettingDialog.TwitterConfiguration.PhotoSizeLimit == 0)
10758 GetTimeline(MyCommon.WORKERTYPE.Configuration, 0, 0, "");
10760 // 権限チェック read/write権限(xAuthで取得したトークン)の場合は再認証を促す
10761 if (MyCommon.TwitterApiInfo.AccessLevel == ApiAccessLevel.ReadWrite)
10763 MessageBox.Show(Properties.Resources.ReAuthorizeText);
10764 SettingStripMenuItem_Click(null, null);
10771 TimerTimeline.Enabled = true;
10774 private bool IsInitialRead()
10776 return _waitTimeline || _waitReply || _waitDm || _waitFav || _waitPubSearch || _waitUserTimeline || _waitLists;
10779 private void doGetFollowersMenu()
10781 GetTimeline(MyCommon.WORKERTYPE.Follower, 1, 0, "");
10782 DispSelectedPost(true);
10785 private void GetFollowersAllToolStripMenuItem_Click(object sender, EventArgs e)
10787 doGetFollowersMenu();
10790 private void doReTweetUnofficial()
10793 if (this.ExistCurrentPost)
10795 if (_curPost.IsDm ||
10796 !StatusText.Enabled) return;
10798 if (_curPost.IsProtect)
10800 MessageBox.Show("Protected.");
10803 string rtdata = _curPost.Text;
10804 rtdata = CreateRetweetUnofficial(rtdata);
10806 StatusText.Text = "RT @" + _curPost.ScreenName + ": " + HttpUtility.HtmlDecode(rtdata);
10808 StatusText.SelectionStart = 0;
10809 StatusText.Focus();
10813 private void ReTweetStripMenuItem_Click(object sender, EventArgs e)
10815 doReTweetUnofficial();
10818 private void doReTweetOfficial(bool isConfirm)
10821 if (this.ExistCurrentPost)
10823 if (_curPost.IsProtect)
10825 MessageBox.Show("Protected.");
10826 _DoFavRetweetFlags = false;
10829 if (_curList.SelectedIndices.Count > 15)
10831 MessageBox.Show(Properties.Resources.RetweetLimitText);
10832 _DoFavRetweetFlags = false;
10835 else if (_curList.SelectedIndices.Count > 1)
10837 string QuestionText = Properties.Resources.RetweetQuestion2;
10838 if (_DoFavRetweetFlags) QuestionText = Properties.Resources.FavoriteRetweetQuestionText1;
10839 switch (MessageBox.Show(QuestionText, "Retweet", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question))
10841 case DialogResult.Cancel:
10842 case DialogResult.No:
10843 _DoFavRetweetFlags = false;
10849 if (_curPost.IsDm || _curPost.IsMe)
10851 _DoFavRetweetFlags = false;
10854 if (!SettingDialog.RetweetNoConfirm)
10856 string Questiontext = Properties.Resources.RetweetQuestion1;
10857 if (_DoFavRetweetFlags) Questiontext = Properties.Resources.FavoritesRetweetQuestionText2;
10858 if (isConfirm && MessageBox.Show(Questiontext, "Retweet", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
10860 _DoFavRetweetFlags = false;
10865 GetWorkerArg args = new GetWorkerArg();
10866 args.ids = new List<long>();
10867 args.sIds = new List<long>();
10868 args.tName = _curTab.Text;
10869 args.type = MyCommon.WORKERTYPE.Retweet;
10870 foreach (int idx in _curList.SelectedIndices)
10872 PostClass post = GetCurTabPost(idx);
10873 if (!post.IsMe && !post.IsProtect && !post.IsDm) args.ids.Add(post.StatusId);
10879 private void ReTweetOriginalStripMenuItem_Click(object sender, EventArgs e)
10881 doReTweetOfficial(true);
10884 private void FavoritesRetweetOriginal()
10886 if (!this.ExistCurrentPost) return;
10887 _DoFavRetweetFlags = true;
10888 doReTweetOfficial(true);
10889 if (_DoFavRetweetFlags)
10891 _DoFavRetweetFlags = false;
10892 FavoriteChange(true, false);
10896 private void FavoritesRetweetUnofficial()
10898 if (this.ExistCurrentPost && !_curPost.IsDm)
10900 _DoFavRetweetFlags = true;
10901 FavoriteChange(true);
10902 if (!_curPost.IsProtect && _DoFavRetweetFlags)
10904 _DoFavRetweetFlags = false;
10905 doReTweetUnofficial();
10910 private string CreateRetweetUnofficial(string status)
10912 // Twitterにより省略されているURLを含むaタグをキャプチャしてリンク先URLへ置き換える
10913 status = Regex.Replace(status, @"<a target=""_self"" href=""(?<url>[^""]+)"" title=""(?<title>[^""]+)""[^>]*>(?<link>[^<]+)</a>", "${title}");
10915 //その他のリンク(@IDなど)を置き換える
10916 status = Regex.Replace(status, @"@<a target=""_self"" href=""https?://twitter.com/(#!/)?(?<url>[^""]+)""[^>]*>(?<link>[^<]+)</a>", "@${url}");
10918 status = Regex.Replace(status, @"<a target=""_self"" href=""(?<url>[^""]+)""[^>]*>(?<link>[^<]+)</a>", "${link}");
10920 if (StatusText.Multiline)
10921 status = Regex.Replace(status, @"(\r\n|\n|\r)?<br>", "\r\n", RegexOptions.IgnoreCase | RegexOptions.Multiline);
10923 status = Regex.Replace(status, @"(\r\n|\n|\r)?<br>", " ", RegexOptions.IgnoreCase | RegexOptions.Multiline);
10926 _reply_to_name = "";
10927 status = status.Replace(" ", " ");
10932 private void DumpPostClassToolStripMenuItem_Click(object sender, EventArgs e)
10934 if (_curPost != null)
10935 DispSelectedPost(true);
10938 private void MenuItemHelp_DropDownOpening(object sender, EventArgs e)
10940 if (MyCommon.DebugBuild || MyCommon.IsKeyDown(Keys.CapsLock, Keys.Control, Keys.Shift))
10941 DebugModeToolStripMenuItem.Visible = true;
10943 DebugModeToolStripMenuItem.Visible = false;
10946 private void ToolStripMenuItemUrlAutoShorten_CheckedChanged(object sender, EventArgs e)
10948 SettingDialog.UrlConvertAuto = ToolStripMenuItemUrlAutoShorten.Checked;
10951 private void ContextMenuPostMode_Opening(object sender, CancelEventArgs e)
10953 ToolStripMenuItemUrlAutoShorten.Checked = SettingDialog.UrlConvertAuto;
10956 private void TraceOutToolStripMenuItem_Click(object sender, EventArgs e)
10958 if (TraceOutToolStripMenuItem.Checked)
10959 MyCommon.TraceFlag = true;
10961 MyCommon.TraceFlag = false;
10964 private void TweenMain_Deactivate(object sender, EventArgs e)
10966 //画面が非アクティブになったら、発言欄の背景色をデフォルトへ
10967 this.StatusText_Leave(StatusText, System.EventArgs.Empty);
10970 private void TabRenameMenuItem_Click(object sender, EventArgs e)
10972 if (string.IsNullOrEmpty(_rclickTabName)) return;
10973 TabRename(ref _rclickTabName);
10976 private void BitlyToolStripMenuItem_Click(object sender, EventArgs e)
10978 UrlConvert(MyCommon.UrlConverter.Bitly);
10981 private void JmpToolStripMenuItem_Click(object sender, EventArgs e)
10983 UrlConvert(MyCommon.UrlConverter.Jmp);
10987 private class GetApiInfoArgs
10990 public ApiInfo info;
10993 private void GetApiInfo_Dowork(object sender, DoWorkEventArgs e)
10995 GetApiInfoArgs args = (GetApiInfoArgs)e.Argument;
10996 e.Result = tw.GetInfoApi(args.info);
10999 private void ApiInfoMenuItem_Click(object sender, EventArgs e)
11001 ApiInfo info = new ApiInfo();
11002 StringBuilder tmp = new StringBuilder();
11003 GetApiInfoArgs args = new GetApiInfoArgs() {tw = tw, info = info};
11005 using (FormInfo dlg = new FormInfo(this, Properties.Resources.ApiInfo6, GetApiInfo_Dowork, null, args))
11008 if ((bool)dlg.Result)
11010 tmp.AppendLine(Properties.Resources.ApiInfo1 + args.info.MaxCount.ToString());
11011 tmp.AppendLine(Properties.Resources.ApiInfo2 + args.info.RemainCount.ToString());
11012 tmp.AppendLine(Properties.Resources.ApiInfo3 + args.info.ResetTime.ToString());
11013 tmp.AppendLine(Properties.Resources.ApiInfo7 + (tw.UserStreamEnabled ? Properties.Resources.Enable : Properties.Resources.Disable).ToString());
11016 tmp.AppendLine(Properties.Resources.ApiInfo8 + args.info.AccessLevel.ToString());
11017 SetStatusLabelUrl();
11020 tmp.AppendLine(Properties.Resources.ApiInfo9 + (args.info.MediaMaxCount < 0 ? Properties.Resources.ApiInfo91 : args.info.MediaMaxCount.ToString()));
11021 tmp.AppendLine(Properties.Resources.ApiInfo10 + (args.info.MediaRemainCount < 0 ? Properties.Resources.ApiInfo91 : args.info.MediaRemainCount.ToString()));
11022 tmp.AppendLine(Properties.Resources.ApiInfo11 + (args.info.MediaResetTime == new DateTime() ? Properties.Resources.ApiInfo91 : args.info.MediaResetTime.ToString()));
11026 tmp.Append(Properties.Resources.ApiInfo5);
11030 MessageBox.Show(tmp.ToString(), Properties.Resources.ApiInfo4, MessageBoxButtons.OK, MessageBoxIcon.Information);
11033 private void FollowCommandMenuItem_Click(object sender, EventArgs e)
11036 if (_curPost != null) id = _curPost.ScreenName;
11040 private void FollowCommand_DoWork(object sender, DoWorkEventArgs e)
11042 FollowRemoveCommandArgs arg = (FollowRemoveCommandArgs)e.Argument;
11043 e.Result = arg.tw.PostFollowCommand(arg.id);
11046 private void FollowCommand(string id)
11048 using (InputTabName inputName = new InputTabName())
11050 inputName.FormTitle = "Follow";
11051 inputName.FormDescription = Properties.Resources.FRMessage1;
11052 inputName.TabName = id;
11053 if (inputName.ShowDialog() == DialogResult.OK &&
11054 !string.IsNullOrEmpty(inputName.TabName.Trim()))
11056 FollowRemoveCommandArgs arg = new FollowRemoveCommandArgs();
11058 arg.id = inputName.TabName.Trim();
11059 using (FormInfo _info = new FormInfo(this, Properties.Resources.FollowCommandText1,
11060 FollowCommand_DoWork,
11064 _info.ShowDialog();
11065 string ret = (string)_info.Result;
11066 if (!string.IsNullOrEmpty(ret))
11067 MessageBox.Show(Properties.Resources.FRMessage2 + ret);
11069 MessageBox.Show(Properties.Resources.FRMessage3);
11075 private void RemoveCommandMenuItem_Click(object sender, EventArgs e)
11078 if (_curPost != null) id = _curPost.ScreenName;
11079 RemoveCommand(id, false);
11082 private class FollowRemoveCommandArgs
11088 private void RemoveCommand_DoWork(object sender , DoWorkEventArgs e)
11090 FollowRemoveCommandArgs arg = (FollowRemoveCommandArgs)e.Argument;
11091 e.Result = arg.tw.PostRemoveCommand(arg.id);
11094 private void RemoveCommand(string id, bool skipInput)
11096 FollowRemoveCommandArgs arg = new FollowRemoveCommandArgs();
11101 using (InputTabName inputName = new InputTabName())
11103 inputName.FormTitle = "Unfollow";
11104 inputName.FormDescription = Properties.Resources.FRMessage1;
11105 inputName.TabName = id;
11106 if (inputName.ShowDialog() == DialogResult.OK &&
11107 !string.IsNullOrEmpty(inputName.TabName.Trim()))
11110 arg.id = inputName.TabName.Trim();
11119 using (FormInfo _info = new FormInfo(this, Properties.Resources.RemoveCommandText1,
11120 RemoveCommand_DoWork,
11124 _info.ShowDialog();
11125 string ret = (string)_info.Result;
11126 if (!string.IsNullOrEmpty(ret))
11127 MessageBox.Show(Properties.Resources.FRMessage2 + ret);
11129 MessageBox.Show(Properties.Resources.FRMessage3);
11133 private void FriendshipMenuItem_Click(object sender, EventArgs e)
11136 if (_curPost != null)
11137 id = _curPost.ScreenName;
11139 ShowFriendship(id);
11142 private class ShowFriendshipArgs
11145 public class FriendshipInfo
11147 public string id = "";
11148 public bool isFollowing = false;
11149 public bool isFollowed = false;
11150 public bool isError = false;
11151 public FriendshipInfo(string id)
11156 public List<FriendshipInfo> ids = new List<FriendshipInfo>();
11159 private void ShowFriendship_DoWork(object sender, DoWorkEventArgs e)
11161 ShowFriendshipArgs arg = (ShowFriendshipArgs)e.Argument;
11162 string result = "";
11163 foreach (ShowFriendshipArgs.FriendshipInfo fInfo in arg.ids)
11165 string rt = arg.tw.GetFriendshipInfo(fInfo.id, ref fInfo.isFollowing, ref fInfo.isFollowed);
11166 if (!string.IsNullOrEmpty(rt))
11168 if (string.IsNullOrEmpty(result)) result = rt;
11169 fInfo.isError = true;
11175 private void ShowFriendship(string id)
11177 ShowFriendshipArgs args = new ShowFriendshipArgs();
11179 using (InputTabName inputName = new InputTabName())
11181 inputName.FormTitle = "Show Friendships";
11182 inputName.FormDescription = Properties.Resources.FRMessage1;
11183 inputName.TabName = id;
11184 if (inputName.ShowDialog() == DialogResult.OK &&
11185 !string.IsNullOrEmpty(inputName.TabName.Trim()))
11188 args.ids.Add(new ShowFriendshipArgs.FriendshipInfo(inputName.TabName.Trim()));
11189 using (FormInfo _info = new FormInfo(this, Properties.Resources.ShowFriendshipText1,
11190 ShowFriendship_DoWork,
11194 _info.ShowDialog();
11195 ret = (string)_info.Result;
11197 string result = "";
11198 if (string.IsNullOrEmpty(ret))
11200 if (args.ids[0].isFollowing)
11202 result = Properties.Resources.GetFriendshipInfo1 + System.Environment.NewLine;
11206 result = Properties.Resources.GetFriendshipInfo2 + System.Environment.NewLine;
11208 if (args.ids[0].isFollowed)
11210 result += Properties.Resources.GetFriendshipInfo3;
11214 result += Properties.Resources.GetFriendshipInfo4;
11216 result = args.ids[0].id + Properties.Resources.GetFriendshipInfo5 + System.Environment.NewLine + result;
11222 MessageBox.Show(result);
11227 private void ShowFriendship(string[] ids)
11229 foreach (string id in ids)
11232 ShowFriendshipArgs args = new ShowFriendshipArgs();
11234 args.ids.Add(new ShowFriendshipArgs.FriendshipInfo(id.Trim()));
11235 using (FormInfo _info = new FormInfo(this, Properties.Resources.ShowFriendshipText1,
11236 ShowFriendship_DoWork,
11240 _info.ShowDialog();
11241 ret = (string)_info.Result;
11243 string result = "";
11244 ShowFriendshipArgs.FriendshipInfo fInfo = args.ids[0];
11246 if (string.IsNullOrEmpty(ret))
11249 if (fInfo.isFollowing)
11251 ff += Properties.Resources.GetFriendshipInfo1;
11255 ff += Properties.Resources.GetFriendshipInfo2;
11258 ff += System.Environment.NewLine + " ";
11259 if (fInfo.isFollowed)
11261 ff += Properties.Resources.GetFriendshipInfo3;
11265 ff += Properties.Resources.GetFriendshipInfo4;
11267 result += fInfo.id + Properties.Resources.GetFriendshipInfo5 + System.Environment.NewLine + ff;
11268 if (fInfo.isFollowing)
11270 if (MessageBox.Show(
11271 Properties.Resources.GetFriendshipInfo7 + System.Environment.NewLine + result, Properties.Resources.GetFriendshipInfo8,
11272 MessageBoxButtons.YesNo,
11273 MessageBoxIcon.Question,
11274 MessageBoxDefaultButton.Button2) == DialogResult.Yes)
11276 RemoveCommand(fInfo.id, true);
11281 MessageBox.Show(result);
11286 MessageBox.Show(ret);
11291 private void OwnStatusMenuItem_Click(object sender, EventArgs e)
11293 doShowUserStatus(tw.Username, false);
11294 //if (!string.IsNullOrEmpty(tw.UserInfoXml))
11296 // doShowUserStatus(tw.Username, false);
11300 // MessageBox.Show(Properties.Resources.ShowYourProfileText1, "Your status", MessageBoxButtons.OK, MessageBoxIcon.Information);
11305 // TwitterIDでない固定文字列を調べる(文字列検証のみ 実際に取得はしない)
11306 // URLから切り出した文字列を渡す
11308 public bool IsTwitterId(string name)
11310 if (SettingDialog.TwitterConfiguration.NonUsernamePaths == null || SettingDialog.TwitterConfiguration.NonUsernamePaths.Length == 0)
11311 return !Regex.Match(name, @"^(about|jobs|tos|privacy|who_to_follow|download|messages)$", RegexOptions.IgnoreCase).Success;
11313 return !SettingDialog.TwitterConfiguration.NonUsernamePaths.Contains(name.ToLower());
11316 private string GetUserId()
11318 Match m = Regex.Match(this._postBrowserStatusText, @"^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?$");
11319 if (m.Success && IsTwitterId(m.Result("${ScreenName}")))
11320 return m.Result("${ScreenName}");
11325 private void FollowContextMenuItem_Click(object sender, EventArgs e)
11327 string name = GetUserId();
11328 if (name != null) FollowCommand(name);
11331 private void RemoveContextMenuItem_Click(object sender, EventArgs e)
11333 string name = GetUserId();
11334 if (name != null) RemoveCommand(name, false);
11337 private void FriendshipContextMenuItem_Click(object sender, EventArgs e)
11339 string name = GetUserId();
11340 if (name != null) ShowFriendship(name);
11343 private void FriendshipAllMenuItem_Click(object sender, EventArgs e)
11345 MatchCollection ma = Regex.Matches(this.PostBrowser.DocumentText, @"href=""https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?""");
11346 List<string> ids = new List<string>();
11347 foreach (Match mu in ma)
11349 if (mu.Result("${ScreenName}").ToLower() != tw.Username.ToLower())
11351 ids.Add(mu.Result("${ScreenName}"));
11354 ShowFriendship(ids.ToArray());
11357 private void ShowUserStatusContextMenuItem_Click(object sender, EventArgs e)
11359 string name = GetUserId();
11360 if (name != null) ShowUserStatus(name);
11363 private void SearchPostsDetailToolStripMenuItem_Click(object sender, EventArgs e)
11365 string name = GetUserId();
11366 if (name != null) AddNewTabForUserTimeline(name);
11369 private void SearchAtPostsDetailToolStripMenuItem_Click(object sender, EventArgs e)
11371 string name = GetUserId();
11372 if (name != null) AddNewTabForSearch("@" + name);
11375 private void IdeographicSpaceToSpaceToolStripMenuItem_Click(object sender, EventArgs e)
11377 _modifySettingCommon = true;
11380 private void ToolStripFocusLockMenuItem_CheckedChanged(object sender, EventArgs e)
11382 _modifySettingCommon = true;
11385 private void doQuote()
11389 if (this.ExistCurrentPost)
11391 if (_curPost.IsDm ||
11392 !StatusText.Enabled) return;
11394 if (_curPost.IsProtect)
11396 MessageBox.Show("Protected.");
11399 string rtdata = _curPost.Text;
11400 rtdata = CreateRetweetUnofficial(rtdata);
11402 StatusText.Text = " QT @" + _curPost.ScreenName + ": " + HttpUtility.HtmlDecode(rtdata);
11403 if (_curPost.RetweetedId == 0)
11405 _reply_to_id = _curPost.StatusId;
11409 _reply_to_id = _curPost.RetweetedId;
11411 _reply_to_name = _curPost.ScreenName;
11413 StatusText.SelectionStart = 0;
11414 StatusText.Focus();
11418 private void QuoteStripMenuItem_Click(object sender, EventArgs e) // Handles QuoteStripMenuItem.Click, QtOpMenuItem.Click
11423 private void SearchButton_Click(object sender, EventArgs e)
11426 Control pnl = ((Control)sender).Parent;
11427 if (pnl == null) return;
11428 string tbName = pnl.Parent.Text;
11429 TabClass tb = _statuses.Tabs[tbName];
11430 ComboBox cmb = (ComboBox)pnl.Controls["comboSearch"];
11431 ComboBox cmbLang = (ComboBox)pnl.Controls["comboLang"];
11432 ComboBox cmbusline = (ComboBox)pnl.Controls["comboUserline"];
11433 cmb.Text = cmb.Text.Trim();
11434 // 検索式演算子 OR についてのみ大文字しか認識しないので強制的に大文字とする
11435 bool Quote = false;
11436 StringBuilder buf = new StringBuilder();
11437 char[] c = cmb.Text.ToCharArray();
11438 for (int cnt = 0; cnt < cmb.Text.Length; cnt++)
11440 if (cnt > cmb.Text.Length - 4)
11442 buf.Append(cmb.Text.Substring(cnt));
11451 if (!Quote && cmb.Text.Substring(cnt, 4).Equals(" or ", StringComparison.OrdinalIgnoreCase))
11453 buf.Append(" OR ");
11458 buf.Append(c[cnt]);
11460 cmb.Text = buf.ToString();
11462 tb.SearchWords = cmb.Text;
11463 tb.SearchLang = cmbLang.Text;
11464 if (string.IsNullOrEmpty(cmb.Text))
11466 ((DetailsListView)ListTab.SelectedTab.Tag).Focus();
11470 if (tb.IsQueryChanged())
11472 int idx = ((ComboBox)pnl.Controls["comboSearch"]).Items.IndexOf(tb.SearchWords);
11473 if (idx > -1) ((ComboBox)pnl.Controls["comboSearch"]).Items.RemoveAt(idx);
11474 ((ComboBox)pnl.Controls["comboSearch"]).Items.Insert(0, tb.SearchWords);
11475 cmb.Text = tb.SearchWords;
11477 DetailsListView lst = (DetailsListView)pnl.Parent.Tag;
11478 lst.VirtualListSize = 0;
11480 _statuses.ClearTabIds(tbName);
11481 SaveConfigsTabs(); //検索条件の保存
11484 GetTimeline(MyCommon.WORKERTYPE.PublicSearch, 1, 0, tbName);
11485 ((DetailsListView)ListTab.SelectedTab.Tag).Focus();
11488 private void RefreshMoreStripMenuItem_Click(object sender, EventArgs e)
11494 private void UndoRemoveTabMenuItem_Click(object sender, EventArgs e)
11496 if (_statuses.RemovedTab.Count == 0)
11498 MessageBox.Show("There isn't removed tab.", "Undo", MessageBoxButtons.OK, MessageBoxIcon.Information);
11503 TabClass tb = _statuses.RemovedTab.Pop();
11504 string renamed = tb.TabName;
11505 for (int i = 1; i < int.MaxValue; i++)
11507 if (!_statuses.ContainsTab(renamed)) break;
11508 renamed = tb.TabName + "(" + i.ToString() + ")";
11510 tb.TabName = renamed;
11511 _statuses.Tabs.Add(renamed, tb);
11512 AddNewTab(renamed, false, tb.TabType, tb.ListInfo);
11513 ListTab.SelectedIndex = ListTab.TabPages.Count - 1;
11518 private void doMoveToRTHome()
11520 if (_curList.SelectedIndices.Count > 0)
11522 PostClass post = GetCurTabPost(_curList.SelectedIndices[0]);
11523 if (post.RetweetedId > 0)
11525 OpenUriAsync("http://twitter.com/" + GetCurTabPost(_curList.SelectedIndices[0]).RetweetedBy);
11530 private void MoveToRTHomeMenuItem_Click(object sender, EventArgs e)
11535 private void IdFilterAddMenuItem_Click(object sender, EventArgs e)
11537 string name = GetUserId();
11543 if (_curList.SelectedIndices.Count == 0) return;
11546 if (!SelectTab(out tabName)) return;
11550 MoveOrCopy(ref mv, ref mk);
11552 FiltersClass fc = new FiltersClass();
11553 fc.NameFilter = name;
11554 fc.SearchBoth = true;
11557 fc.UseRegex = false;
11558 fc.SearchUrl = false;
11559 _statuses.Tabs[tabName].AddFilter(fc);
11563 this.Cursor = Cursors.WaitCursor;
11567 _curItemIndex = -1;
11568 _statuses.FilterAll();
11569 foreach (TabPage tb in ListTab.TabPages)
11571 ((DetailsListView)tb.Tag).VirtualListSize = _statuses.Tabs[tb.Text].AllCount;
11572 if (_statuses.Tabs[tb.Text].UnreadCount > 0)
11574 if (SettingDialog.TabIconDisp)
11579 if (SettingDialog.TabIconDisp)
11580 tb.ImageIndex = -1;
11583 if (!SettingDialog.TabIconDisp) ListTab.Refresh();
11587 this.Cursor = Cursors.Default;
11593 private void ListManageUserContextToolStripMenuItem_Click(object sender, EventArgs e)
11597 ToolStripMenuItem menuItem = (ToolStripMenuItem)sender;
11599 if (menuItem.Owner == this.ContextMenuPostBrowser)
11601 user = GetUserId();
11602 if (user == null) return;
11604 else if (this._curPost != null)
11606 user = this._curPost.ScreenName;
11613 if (TabInformations.GetInstance().SubscribableLists.Count == 0)
11615 string res = this.tw.GetListsApi();
11617 if (!string.IsNullOrEmpty(res))
11619 MessageBox.Show("Failed to get lists. (" + res + ")");
11624 using (MyLists listSelectForm = new MyLists(user, this.tw))
11626 listSelectForm.ShowDialog(this);
11630 private void SearchControls_Enter(object sender, EventArgs e)
11632 Control pnl = (Control)sender;
11633 foreach (Control ctl in pnl.Controls)
11635 ctl.TabStop = true;
11639 private void SearchControls_Leave(object sender, EventArgs e)
11641 Control pnl = (Control)sender;
11642 foreach (Control ctl in pnl.Controls)
11644 ctl.TabStop = false;
11648 private void PublicSearchQueryMenuItem_Click(object sender, EventArgs e)
11650 if (ListTab.SelectedTab != null)
11652 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType != MyCommon.TabUsageType.PublicSearch) return;
11653 ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"].Focus();
11657 private void UseHashtagMenuItem_Click(object sender, EventArgs e)
11659 Match m = Regex.Match(this._postBrowserStatusText, @"^https?://twitter.com/search\?q=%23(?<hash>.+)$");
11662 HashMgr.SetPermanentHash("#" + m.Result("${hash}"));
11663 HashStripSplitButton.Text = HashMgr.UseHash;
11664 HashToggleMenuItem.Checked = true;
11665 HashToggleToolStripMenuItem.Checked = true;
11667 _modifySettingCommon = true;
11671 private void StatusLabel_DoubleClick(object sender, EventArgs e)
11673 MessageBox.Show(StatusLabel.TextHistory, "Logs", MessageBoxButtons.OK, MessageBoxIcon.None);
11676 private void HashManageMenuItem_Click(object sender, EventArgs e)
11678 DialogResult rslt = DialogResult.Cancel;
11681 rslt = HashMgr.ShowDialog();
11687 this.TopMost = SettingDialog.AlwaysTop;
11688 if (rslt == DialogResult.Cancel) return;
11689 if (!string.IsNullOrEmpty(HashMgr.UseHash))
11691 HashStripSplitButton.Text = HashMgr.UseHash;
11692 HashToggleMenuItem.Checked = true;
11693 HashToggleToolStripMenuItem.Checked = true;
11697 HashStripSplitButton.Text = "#[-]";
11698 HashToggleMenuItem.Checked = false;
11699 HashToggleToolStripMenuItem.Checked = false;
11701 //if (HashMgr.IsInsert && HashMgr.UseHash != "")
11703 // int sidx = StatusText.SelectionStart;
11704 // string hash = HashMgr.UseHash + " ";
11707 // if (StatusText.Text.Substring(sidx - 1, 1) != " ")
11708 // hash = " " + hash;
11710 // StatusText.Text = StatusText.Text.Insert(sidx, hash);
11711 // sidx += hash.Length;
11712 // StatusText.SelectionStart = sidx;
11713 // StatusText.Focus();
11715 _modifySettingCommon = true;
11716 this.StatusText_TextChanged(null, null);
11719 private void HashToggleMenuItem_Click(object sender, EventArgs e)
11721 HashMgr.ToggleHash();
11722 if (!string.IsNullOrEmpty(HashMgr.UseHash))
11724 HashStripSplitButton.Text = HashMgr.UseHash;
11725 HashToggleMenuItem.Checked = true;
11726 HashToggleToolStripMenuItem.Checked = true;
11730 HashStripSplitButton.Text = "#[-]";
11731 HashToggleMenuItem.Checked = false;
11732 HashToggleToolStripMenuItem.Checked = false;
11734 _modifySettingCommon = true;
11735 this.StatusText_TextChanged(null, null);
11738 private void HashStripSplitButton_ButtonClick(object sender, EventArgs e)
11740 HashToggleMenuItem_Click(null, null);
11743 private void MenuItemOperate_DropDownOpening(object sender, EventArgs e)
11745 if (ListTab.SelectedTab == null) return;
11746 if (_statuses == null || _statuses.Tabs == null || !_statuses.Tabs.ContainsKey(ListTab.SelectedTab.Text)) return;
11747 if (!this.ExistCurrentPost)
11749 this.ReplyOpMenuItem.Enabled = false;
11750 this.ReplyAllOpMenuItem.Enabled = false;
11751 this.DmOpMenuItem.Enabled = false;
11752 this.ShowProfMenuItem.Enabled = false;
11753 this.ShowUserTimelineToolStripMenuItem.Enabled = false;
11754 this.ListManageMenuItem.Enabled = false;
11755 this.OpenFavOpMenuItem.Enabled = false;
11756 this.CreateTabRuleOpMenuItem.Enabled = false;
11757 this.CreateIdRuleOpMenuItem.Enabled = false;
11758 this.ReadOpMenuItem.Enabled = false;
11759 this.UnreadOpMenuItem.Enabled = false;
11763 this.ReplyOpMenuItem.Enabled = true;
11764 this.ReplyAllOpMenuItem.Enabled = true;
11765 this.DmOpMenuItem.Enabled = true;
11766 this.ShowProfMenuItem.Enabled = true;
11767 this.ShowUserTimelineToolStripMenuItem.Enabled = true;
11768 this.ListManageMenuItem.Enabled = true;
11769 this.OpenFavOpMenuItem.Enabled = true;
11770 this.CreateTabRuleOpMenuItem.Enabled = true;
11771 this.CreateIdRuleOpMenuItem.Enabled = true;
11772 this.ReadOpMenuItem.Enabled = true;
11773 this.UnreadOpMenuItem.Enabled = true;
11776 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.DirectMessage || !this.ExistCurrentPost || _curPost.IsDm)
11778 this.FavOpMenuItem.Enabled = false;
11779 this.UnFavOpMenuItem.Enabled = false;
11780 this.OpenStatusOpMenuItem.Enabled = false;
11781 this.OpenFavotterOpMenuItem.Enabled = false;
11782 this.ShowRelatedStatusesMenuItem2.Enabled = false;
11783 this.RtOpMenuItem.Enabled = false;
11784 this.RtUnOpMenuItem.Enabled = false;
11785 this.QtOpMenuItem.Enabled = false;
11786 this.FavoriteRetweetMenuItem.Enabled = false;
11787 this.FavoriteRetweetUnofficialMenuItem.Enabled = false;
11788 if (this.ExistCurrentPost && _curPost.IsDm) this.DelOpMenuItem.Enabled = true;
11792 this.FavOpMenuItem.Enabled = true;
11793 this.UnFavOpMenuItem.Enabled = true;
11794 this.OpenStatusOpMenuItem.Enabled = true;
11795 this.OpenFavotterOpMenuItem.Enabled = true;
11796 this.ShowRelatedStatusesMenuItem2.Enabled = true; //PublicSearchの時問題出るかも
11800 this.RtOpMenuItem.Enabled = false;
11801 this.FavoriteRetweetMenuItem.Enabled = false;
11802 this.DelOpMenuItem.Enabled = true;
11806 this.DelOpMenuItem.Enabled = false;
11807 if (_curPost.IsProtect)
11809 this.RtOpMenuItem.Enabled = false;
11810 this.RtUnOpMenuItem.Enabled = false;
11811 this.QtOpMenuItem.Enabled = false;
11812 this.FavoriteRetweetMenuItem.Enabled = false;
11813 this.FavoriteRetweetUnofficialMenuItem.Enabled = false;
11817 this.RtOpMenuItem.Enabled = true;
11818 this.RtUnOpMenuItem.Enabled = true;
11819 this.QtOpMenuItem.Enabled = true;
11820 this.FavoriteRetweetMenuItem.Enabled = true;
11821 this.FavoriteRetweetUnofficialMenuItem.Enabled = true;
11826 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType != MyCommon.TabUsageType.Favorites)
11828 this.RefreshPrevOpMenuItem.Enabled = true;
11832 this.RefreshPrevOpMenuItem.Enabled = false;
11834 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.PublicSearch
11835 || !this.ExistCurrentPost
11836 || !(_curPost.InReplyToStatusId > 0))
11838 OpenRepSourceOpMenuItem.Enabled = false;
11842 OpenRepSourceOpMenuItem.Enabled = true;
11844 if (!this.ExistCurrentPost || string.IsNullOrEmpty(_curPost.RetweetedBy))
11846 OpenRterHomeMenuItem.Enabled = false;
11850 OpenRterHomeMenuItem.Enabled = true;
11854 private void MenuItemTab_DropDownOpening(object sender, EventArgs e)
11856 ContextMenuTabProperty_Opening(sender, null);
11859 public Twitter TwitterInstance
11864 private void SplitContainer3_SplitterMoved(object sender, SplitterEventArgs e)
11866 if (this.WindowState == FormWindowState.Normal && !_initialLayout)
11868 _mySpDis3 = SplitContainer3.SplitterDistance;
11869 _modifySettingLocal = true;
11873 private void MenuItemEdit_DropDownOpening(object sender, EventArgs e)
11875 if (_statuses.RemovedTab.Count == 0)
11877 UndoRemoveTabMenuItem.Enabled = false;
11881 UndoRemoveTabMenuItem.Enabled = true;
11883 if (ListTab.SelectedTab != null)
11885 if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.PublicSearch)
11886 PublicSearchQueryMenuItem.Enabled = true;
11888 PublicSearchQueryMenuItem.Enabled = false;
11892 PublicSearchQueryMenuItem.Enabled = false;
11894 if (!this.ExistCurrentPost)
11896 this.CopySTOTMenuItem.Enabled = false;
11897 this.CopyURLMenuItem.Enabled = false;
11898 this.CopyUserIdStripMenuItem.Enabled = false;
11902 this.CopySTOTMenuItem.Enabled = true;
11903 this.CopyURLMenuItem.Enabled = true;
11904 this.CopyUserIdStripMenuItem.Enabled = true;
11905 if (_curPost.IsDm) this.CopyURLMenuItem.Enabled = false;
11906 if (_curPost.IsProtect) this.CopySTOTMenuItem.Enabled = false;
11910 private void NotifyIcon1_MouseMove(object sender, MouseEventArgs e)
11912 SetNotifyIconText();
11915 private void UserStatusToolStripMenuItem_Click(object sender, EventArgs e)
11918 if (_curPost != null)
11920 id = _curPost.ScreenName;
11922 ShowUserStatus(id);
11925 private class GetUserInfoArgs
11929 public TwitterDataModel.User user;
11932 private void GetUserInfo_DoWork(object sender, DoWorkEventArgs e)
11934 GetUserInfoArgs args = (GetUserInfoArgs)e.Argument;
11935 e.Result = args.tw.GetUserInfo(args.id, ref args.user);
11938 private void doShowUserStatus(string id, bool ShowInputDialog)
11940 TwitterDataModel.User user = null;
11941 GetUserInfoArgs args = new GetUserInfoArgs();
11942 if (ShowInputDialog)
11944 using (InputTabName inputName = new InputTabName())
11946 inputName.FormTitle = "Show UserStatus";
11947 inputName.FormDescription = Properties.Resources.FRMessage1;
11948 inputName.TabName = id;
11949 if (inputName.ShowDialog() == DialogResult.OK &&
11950 !string.IsNullOrEmpty(inputName.TabName.Trim()))
11952 id = inputName.TabName.Trim();
11956 using (FormInfo _info = new FormInfo(this, Properties.Resources.doShowUserStatusText1,
11957 GetUserInfo_DoWork,
11961 _info.ShowDialog();
11962 string ret = (string)_info.Result;
11963 if (string.IsNullOrEmpty(ret))
11964 doShowUserStatus(args.user);
11966 MessageBox.Show(ret);
11976 using (FormInfo _info = new FormInfo(this, Properties.Resources.doShowUserStatusText1,
11977 GetUserInfo_DoWork,
11981 _info.ShowDialog();
11982 string ret = (string)_info.Result;
11983 if (string.IsNullOrEmpty(ret))
11985 doShowUserStatus(args.user);
11989 MessageBox.Show(ret);
11995 private void doShowUserStatus(TwitterDataModel.User user)
11997 using (ShowUserInfo userinfo = new ShowUserInfo())
11999 userinfo.Owner = this;
12000 userinfo.User = user;
12001 userinfo.ShowDialog(this);
12003 this.BringToFront();
12007 private void ShowUserStatus(string id, bool ShowInputDialog)
12009 doShowUserStatus(id, ShowInputDialog);
12012 private void ShowUserStatus(string id)
12014 doShowUserStatus(id, true);
12017 private void FollowToolStripMenuItem_Click(object sender, EventArgs e)
12019 if (NameLabel.Tag != null)
12021 string id = (string)NameLabel.Tag;
12022 if (id != tw.Username)
12029 private void UnFollowToolStripMenuItem_Click(object sender, EventArgs e)
12031 if (NameLabel.Tag != null)
12033 string id = (string)NameLabel.Tag;
12034 if (id != tw.Username)
12036 RemoveCommand(id, false);
12041 private void ShowFriendShipToolStripMenuItem_Click(object sender, EventArgs e)
12043 if (NameLabel.Tag != null)
12045 string id = (string)NameLabel.Tag;
12046 if (id != tw.Username)
12048 ShowFriendship(id);
12053 private void ShowUserStatusToolStripMenuItem_Click(object sender, EventArgs e)
12055 if (NameLabel.Tag != null)
12057 string id = (string)NameLabel.Tag;
12058 ShowUserStatus(id, false);
12062 private void SearchPostsDetailNameToolStripMenuItem_Click(object sender, EventArgs e)
12064 if (NameLabel.Tag != null)
12066 string id = (string)NameLabel.Tag;
12067 AddNewTabForUserTimeline(id);
12071 private void SearchAtPostsDetailNameToolStripMenuItem_Click(object sender, EventArgs e)
12073 if (NameLabel.Tag != null)
12075 string id = (string)NameLabel.Tag;
12076 AddNewTabForSearch("@" + id);
12080 private void ShowProfileMenuItem_Click(object sender, EventArgs e)
12082 if (_curPost != null)
12084 ShowUserStatus(_curPost.ScreenName, false);
12088 private void GetRetweet_DoWork(object sender, DoWorkEventArgs e)
12093 if (_curPost.RetweetedId > 0)
12095 statusid = _curPost.RetweetedId;
12099 statusid = _curPost.StatusId;
12101 tw.GetStatus_Retweeted_Count(statusid, ref counter);
12103 e.Result = counter;
12106 private void RtCountMenuItem_Click(object sender, EventArgs e)
12108 if (this.ExistCurrentPost)
12110 using (FormInfo _info = new FormInfo(this, Properties.Resources.RtCountMenuItem_ClickText1,
12111 GetRetweet_DoWork))
12113 int retweet_count = 0;
12116 _info.ShowDialog();
12117 retweet_count = (int)_info.Result;
12118 if (retweet_count < 0)
12120 MessageBox.Show(Properties.Resources.RtCountText2);
12124 MessageBox.Show(retweet_count.ToString() + Properties.Resources.RtCountText1);
12130 private HookGlobalHotkey _hookGlobalHotkey;
12133 _hookGlobalHotkey = new HookGlobalHotkey(this);
12134 // この呼び出しは、Windows フォーム デザイナで必要です。
12135 InitializeComponent();
12137 // InitializeComponent() 呼び出しの後で初期化を追加します。
12139 this.SettingDialog.IntervalChanged += this.TimerInterval_Changed;
12140 this.TimerTimeline.Elapsed += this.TimerTimeline_Elapsed;
12141 this._hookGlobalHotkey.HotkeyPressed += _hookGlobalHotkey_HotkeyPressed;
12142 this.gh.NotifyClicked += GrowlHelper_Callback;
12144 this._apiGauge.Control.Size = new Size(70, 22);
12145 this._apiGauge.Control.Margin = new Padding(0, 3, 0, 2);
12146 this._apiGauge.GaugeHeight = 8;
12147 this._apiGauge.Control.DoubleClick += this.ApiInfoMenuItem_Click;
12148 this.StatusStrip1.Items.Insert(2, this._apiGauge);
12150 this.ReplaceAppName();
12153 private void _hookGlobalHotkey_HotkeyPressed(object sender, KeyEventArgs e)
12155 if ((this.WindowState == FormWindowState.Normal || this.WindowState == FormWindowState.Maximized) && this.Visible && Form.ActiveForm == this)
12158 this.Visible = false;
12160 else if (Form.ActiveForm == null)
12162 this.Visible = true;
12163 if (this.WindowState == FormWindowState.Minimized) this.WindowState = FormWindowState.Normal;
12165 this.BringToFront();
12166 this.StatusText.Focus();
12170 private void UserPicture_MouseEnter(object sender, EventArgs e)
12172 this.UserPicture.Cursor = Cursors.Hand;
12175 private void UserPicture_MouseLeave(object sender, EventArgs e)
12177 this.UserPicture.Cursor = Cursors.Default;
12180 private void UserPicture_DoubleClick(object sender, EventArgs e)
12182 if (NameLabel.Tag != null)
12184 OpenUriAsync(MyCommon.TwitterUrl + NameLabel.Tag.ToString());
12188 private void SplitContainer2_MouseDoubleClick(object sender, MouseEventArgs e)
12190 this.MultiLineMenuItem.PerformClick();
12193 public PostClass CurPost
12195 get { return _curPost; }
12198 public bool IsPreviewEnable
12200 get { return SettingDialog.PreviewEnable; }
12204 private void ImageSelectMenuItem_Click(object sender, EventArgs e)
12206 if (ImageSelectionPanel.Visible == true)
12208 ImagefilePathText.CausesValidation = false;
12209 TimelinePanel.Visible = true;
12210 TimelinePanel.Enabled = true;
12211 ImageSelectionPanel.Visible = false;
12212 ImageSelectionPanel.Enabled = false;
12213 ((DetailsListView)ListTab.SelectedTab.Tag).Focus();
12214 ImagefilePathText.CausesValidation = true;
12218 ImageSelectionPanel.Visible = true;
12219 ImageSelectionPanel.Enabled = true;
12220 TimelinePanel.Visible = false;
12221 TimelinePanel.Enabled = false;
12222 ImagefilePathText.Focus();
12226 private void FilePickButton_Click(object sender, EventArgs e)
12228 if (string.IsNullOrEmpty(this.ImageService)) return;
12229 OpenFileDialog1.Filter = this.pictureService[this.ImageService].GetFileOpenDialogFilter();
12230 OpenFileDialog1.Title = Properties.Resources.PickPictureDialog1;
12231 OpenFileDialog1.FileName = "";
12235 this.AllowDrop = false;
12236 if (OpenFileDialog1.ShowDialog() == DialogResult.Cancel) return;
12240 this.AllowDrop = true;
12243 ImagefilePathText.Text = OpenFileDialog1.FileName;
12244 ImageFromSelectedFile();
12247 private void ImagefilePathText_Validating(object sender, CancelEventArgs e)
12249 if (ImageCancelButton.Focused)
12251 ImagefilePathText.CausesValidation = false;
12254 ImagefilePathText.Text = ImagefilePathText.Text.Trim();
12255 if (string.IsNullOrEmpty(ImagefilePathText.Text))
12257 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12258 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12262 ImageFromSelectedFile();
12266 private void ImageFromSelectedFile()
12270 if (string.IsNullOrEmpty(ImagefilePathText.Text.Trim()) || string.IsNullOrEmpty(this.ImageService))
12272 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12273 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12274 ImagefilePathText.Text = "";
12278 FileInfo fl = new FileInfo(ImagefilePathText.Text.Trim());
12279 if (!this.pictureService[this.ImageService].CheckValidExtension(fl.Extension))
12282 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12283 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12284 ImagefilePathText.Text = "";
12288 if (!this.pictureService[this.ImageService].CheckValidFilesize(fl.Extension, fl.Length))
12291 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12292 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12293 ImagefilePathText.Text = "";
12294 MessageBox.Show("File is too large.");
12298 switch (this.pictureService[this.ImageService].GetFileType(fl.Extension))
12300 case MyCommon.UploadFileType.Invalid:
12301 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12302 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12303 ImagefilePathText.Text = "";
12305 case MyCommon.UploadFileType.Picture:
12307 using (FileStream fs = new FileStream(ImagefilePathText.Text, FileMode.Open, FileAccess.Read))
12309 img = Image.FromStream(fs);
12311 ImageSelectedPicture.Image = (new HttpVarious()).CheckValidImage(
12315 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Picture;
12317 case MyCommon.UploadFileType.MultiMedia:
12318 ImageSelectedPicture.Image = Properties.Resources.MultiMediaImage;
12319 ImageSelectedPicture.Tag = MyCommon.UploadFileType.MultiMedia;
12322 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12323 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12324 ImagefilePathText.Text = "";
12328 catch (FileNotFoundException)
12330 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12331 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12332 ImagefilePathText.Text = "";
12333 MessageBox.Show("File not found.");
12337 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12338 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12339 ImagefilePathText.Text = "";
12340 MessageBox.Show("The type of this file is not image.");
12344 private void ImageSelection_KeyDown(object sender, KeyEventArgs e)
12346 if (e.KeyCode == Keys.Escape)
12348 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12349 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12350 TimelinePanel.Visible = true;
12351 TimelinePanel.Enabled = true;
12352 ImageSelectionPanel.Visible = false;
12353 ImageSelectionPanel.Enabled = false;
12354 ((DetailsListView)ListTab.SelectedTab.Tag).Focus();
12355 ImagefilePathText.CausesValidation = true;
12359 private void ImageSelection_KeyPress(object sender, KeyPressEventArgs e)
12361 if (Convert.ToInt32(e.KeyChar) == 0x1B)
12363 ImagefilePathText.CausesValidation = false;
12368 private void ImageSelection_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
12370 if (e.KeyCode == Keys.Escape)
12372 ImagefilePathText.CausesValidation = false;
12376 private void SetImageServiceCombo()
12379 if (ImageServiceCombo.SelectedIndex > -1) svc = ImageServiceCombo.SelectedItem.ToString();
12380 ImageServiceCombo.Items.Clear();
12381 ImageServiceCombo.Items.Add("TwitPic");
12382 ImageServiceCombo.Items.Add("img.ly");
12383 ImageServiceCombo.Items.Add("yfrog");
12384 ImageServiceCombo.Items.Add("lockerz");
12385 ImageServiceCombo.Items.Add("Twitter");
12387 if (string.IsNullOrEmpty(svc))
12389 ImageServiceCombo.SelectedIndex = 0;
12393 int idx = ImageServiceCombo.Items.IndexOf(svc);
12395 ImageServiceCombo.SelectedIndex = 0;
12397 ImageServiceCombo.SelectedIndex = idx;
12401 private string ImageService
12403 get { return (string)ImageServiceCombo.SelectedItem; }
12406 private void ImageCancelButton_Click(object sender, EventArgs e)
12408 ImagefilePathText.CausesValidation = false;
12409 TimelinePanel.Visible = true;
12410 TimelinePanel.Enabled = true;
12411 ImageSelectionPanel.Visible = false;
12412 ImageSelectionPanel.Enabled = false;
12413 ((DetailsListView)ListTab.SelectedTab.Tag).Focus();
12414 ImagefilePathText.CausesValidation = true;
12417 private void ImageServiceCombo_SelectedIndexChanged(object sender, EventArgs e)
12419 if (ImageSelectedPicture.Tag != null && !string.IsNullOrEmpty(this.ImageService))
12423 FileInfo fi = new FileInfo(ImagefilePathText.Text.Trim());
12424 if (!this.pictureService[this.ImageService].CheckValidFilesize(fi.Extension, fi.Length))
12426 ImagefilePathText.Text = "";
12427 ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
12428 ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
12434 _modifySettingCommon = true;
12435 SaveConfigsAll(false);
12436 if (this.ImageService == "Twitter")
12438 this.StatusText_TextChanged(null, null);
12444 private void ListManageToolStripMenuItem_Click(object sender, EventArgs e)
12446 using (ListManage form = new ListManage(tw))
12448 form.ShowDialog(this);
12452 public bool ModifySettingCommon
12454 set { _modifySettingCommon = value; }
12457 public bool ModifySettingLocal
12459 set { _modifySettingLocal = value; }
12462 public bool ModifySettingAtId
12464 set { _modifySettingAtId = value; }
12467 private void SourceLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
12469 string link = (string)SourceLinkLabel.Tag;
12470 if (!string.IsNullOrEmpty(link) && e.Button == MouseButtons.Left)
12472 OpenUriAsync(link);
12476 private void SourceLinkLabel_MouseEnter(object sender, EventArgs e)
12478 string link = (string)SourceLinkLabel.Tag;
12479 if (!string.IsNullOrEmpty(link))
12481 StatusLabelUrl.Text = link;
12485 private void SourceLinkLabel_MouseLeave(object sender, EventArgs e)
12487 SetStatusLabelUrl();
12490 private void MenuItemCommand_DropDownOpening(object sender, EventArgs e)
12492 if (this.ExistCurrentPost && !_curPost.IsDm)
12493 RtCountMenuItem.Enabled = true;
12495 RtCountMenuItem.Enabled = false;
12497 //if (SettingDialog.UrlConvertAuto && SettingDialog.ShortenTco)
12498 // TinyUrlConvertToolStripMenuItem.Enabled = false;
12500 // TinyUrlConvertToolStripMenuItem.Enabled = true;
12503 private void CopyUserIdStripMenuItem_Click(object sender, EventArgs e)
12508 private void CopyUserId()
12510 if (_curPost == null) return;
12511 string clstr = _curPost.ScreenName;
12514 Clipboard.SetDataObject(clstr, false, 5, 100);
12516 catch (Exception ex)
12518 MessageBox.Show(ex.Message);
12522 private void ShowRelatedStatusesMenuItem_Click(object sender, EventArgs e) // Handles ShowRelatedStatusesMenuItem.Click, ShowRelatedStatusesMenuItem2.Click
12524 TabClass backToTab = _curTab == null ? _statuses.Tabs[ListTab.SelectedTab.Text] : _statuses.Tabs[_curTab.Text];
12525 if (this.ExistCurrentPost && !_curPost.IsDm)
12527 //PublicSearchも除外した方がよい?
12528 if (_statuses.GetTabByType(MyCommon.TabUsageType.Related) == null)
12530 const string TabName = "Related Tweets";
12531 string tName = TabName;
12532 if (!this.AddNewTab(tName, false, MyCommon.TabUsageType.Related))
12534 for (int i = 2; i <= 100; i++)
12536 tName = TabName + i.ToString();
12537 if (this.AddNewTab(tName, false, MyCommon.TabUsageType.Related))
12539 _statuses.AddTab(tName, MyCommon.TabUsageType.Related, null);
12546 _statuses.AddTab(tName, MyCommon.TabUsageType.Related, null);
12548 _statuses.GetTabByName(tName).UnreadManage = false;
12549 _statuses.GetTabByName(tName).Notify = false;
12552 TabClass tb = _statuses.GetTabByType(MyCommon.TabUsageType.Related);
12553 tb.RelationTargetPost = _curPost;
12554 this.ClearTab(tb.TabName, false);
12555 for (int i = 0; i < ListTab.TabPages.Count; i++)
12557 if (tb.TabName == ListTab.TabPages[i].Text)
12559 ListTab.SelectedIndex = i;
12560 ListTabSelect(ListTab.TabPages[i]);
12565 GetTimeline(MyCommon.WORKERTYPE.Related, 1, 1, tb.TabName);
12569 private void CacheInfoMenuItem_Click(object sender, EventArgs e)
12571 StringBuilder buf = new StringBuilder();
12572 buf.AppendFormat("キャッシュメモリ容量 : {0}bytes({1}MB)" + Environment.NewLine, ((ImageDictionary)TIconDic).CacheMemoryLimit, ((ImageDictionary)TIconDic).CacheMemoryLimit / 1048576);
12573 buf.AppendFormat("物理メモリ使用割合 : {0}%" + Environment.NewLine, ((ImageDictionary)TIconDic).PhysicalMemoryLimit);
12574 buf.AppendFormat("キャッシュエントリ保持数 : {0}" + Environment.NewLine, ((ImageDictionary)TIconDic).CacheCount);
12575 buf.AppendFormat("キャッシュエントリ破棄数 : {0}" + Environment.NewLine, ((ImageDictionary)TIconDic).CacheRemoveCount);
12576 MessageBox.Show(buf.ToString(), "アイコンキャッシュ使用状況");
12579 private void tw_UserIdChanged()
12581 this._modifySettingCommon = true;
12584 #region "Userstream"
12585 private bool _isActiveUserstream = false;
12587 private void tw_PostDeleted(long id)
12591 if (InvokeRequired && !IsDisposed)
12593 Invoke((Action) (() =>
12595 _statuses.RemovePostReserve(id);
12596 if (_curTab != null && _statuses.Tabs[_curTab.Text].Contains(id))
12599 _itemCacheIndex = -1;
12601 ((DetailsListView)_curTab.Tag).Update();
12602 if (_curPost != null && _curPost.StatusId == id) DispSelectedPost(true);
12608 catch (ObjectDisposedException)
12612 catch (InvalidOperationException)
12618 private void tw_NewPostFromStream()
12620 if (SettingDialog.ReadOldPosts)
12622 _statuses.SetRead(); //新着時未読クリア
12625 int rsltAddCount = _statuses.DistributePosts();
12628 DateTime tm = DateTime.Now;
12629 if (_tlTimestamps.ContainsKey(tm))
12631 _tlTimestamps[tm] += rsltAddCount;
12635 _tlTimestamps.Add(tm, rsltAddCount);
12637 DateTime oneHour = DateTime.Now.Subtract(new TimeSpan(1, 0, 0));
12638 List<DateTime> keys = new List<DateTime>();
12640 foreach (DateTime key in _tlTimestamps.Keys)
12642 if (key.CompareTo(oneHour) < 0)
12645 _tlCount += _tlTimestamps[key];
12647 foreach (DateTime key in keys)
12649 _tlTimestamps.Remove(key);
12653 //Static DateTime before = Now;
12654 //if (before.Subtract(Now).Seconds > -5) return;
12658 if (SettingDialog.UserstreamPeriodInt > 0) return;
12662 if (InvokeRequired && !IsDisposed)
12664 Invoke(new Action<bool>(RefreshTimeline), true);
12668 catch (ObjectDisposedException)
12672 catch (InvalidOperationException)
12678 private void tw_UserStreamStarted()
12680 this._isActiveUserstream = true;
12683 if (InvokeRequired && !IsDisposed)
12685 Invoke(new MethodInvoker(tw_UserStreamStarted));
12689 catch (ObjectDisposedException)
12693 catch (InvalidOperationException)
12698 MenuItemUserStream.Text = "&UserStream ▶";
12699 MenuItemUserStream.Enabled = true;
12700 StopToolStripMenuItem.Text = "&Stop";
12701 StopToolStripMenuItem.Enabled = true;
12703 StatusLabel.Text = "UserStream Started.";
12706 private void tw_UserStreamStopped()
12708 this._isActiveUserstream = false;
12711 if (InvokeRequired && !IsDisposed)
12713 Invoke(new MethodInvoker(tw_UserStreamStopped));
12717 catch (ObjectDisposedException)
12721 catch (InvalidOperationException)
12726 MenuItemUserStream.Text = "&UserStream ■";
12727 MenuItemUserStream.Enabled = true;
12728 StopToolStripMenuItem.Text = "&Start";
12729 StopToolStripMenuItem.Enabled = true;
12731 StatusLabel.Text = "UserStream Stopped.";
12734 private void tw_UserStreamEventArrived(Twitter.FormattedEvent ev)
12738 if (InvokeRequired && !IsDisposed)
12740 Invoke(new Action<Twitter.FormattedEvent>(tw_UserStreamEventArrived), ev);
12744 catch (ObjectDisposedException)
12748 catch (InvalidOperationException)
12752 StatusLabel.Text = "Event: " + ev.Event;
12753 //if (ev.Event == "favorite")
12755 // NotifyFavorite(ev);
12758 if (ev.Event == "favorite" || ev.Event == "unfavorite")
12760 if (_curTab != null && _statuses.Tabs[_curTab.Text].Contains(ev.Id))
12763 _itemCacheIndex = -1;
12765 ((DetailsListView)_curTab.Tag).Update();
12767 if (ev.Event == "unfavorite" && ev.Username.ToLower().Equals(tw.Username.ToLower()))
12769 RemovePostFromFavTab(new long[] {ev.Id});
12774 private void NotifyEvent(Twitter.FormattedEvent ev)
12777 if (BalloonRequired(ev))
12779 NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
12780 //if (SettingDialog.DispUsername) NotifyIcon1.BalloonTipTitle = tw.Username + " - "; else NotifyIcon1.BalloonTipTitle = "";
12781 //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [" + ev.Event.ToUpper() + "] by " + ((string)(!string.IsNullOrEmpty(ev.Username) ? ev.Username : ""), string);
12782 StringBuilder title = new StringBuilder();
12783 if (SettingDialog.DispUsername)
12785 title.Append(tw.Username);
12786 title.Append(" - ");
12792 title.Append(Application.ProductName);
12793 title.Append(" [");
12794 title.Append(ev.Event.ToUpper());
12795 title.Append("] by ");
12796 if (!string.IsNullOrEmpty(ev.Username))
12798 title.Append(ev.Username.ToString());
12802 //title.Append("");
12805 if (!string.IsNullOrEmpty(ev.Target))
12807 //NotifyIcon1.BalloonTipText = ev.Target;
12812 //NotifyIcon1.BalloonTipText = " ";
12815 //NotifyIcon1.ShowBalloonTip(500);
12816 if (SettingDialog.IsNotifyUseGrowl)
12818 gh.Notify(GrowlHelper.NotifyType.UserStreamEvent,
12819 ev.Id.ToString(), title.ToString(), text);
12823 NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
12824 NotifyIcon1.BalloonTipTitle = title.ToString();
12825 NotifyIcon1.BalloonTipText = text;
12826 NotifyIcon1.ShowBalloonTip(500);
12831 string snd = SettingDialog.EventSoundFile;
12832 if (!_initial && SettingDialog.PlaySound && !string.IsNullOrEmpty(snd))
12834 if ((ev.Eventtype & SettingDialog.EventNotifyFlag) != 0 && IsMyEventNotityAsEventType(ev))
12838 string dir = Application.StartupPath;
12839 if (Directory.Exists(Path.Combine(dir, "Sounds")))
12841 dir = Path.Combine(dir, "Sounds");
12843 using (SoundPlayer player = new SoundPlayer(Path.Combine(dir, snd)))
12855 private void StopToolStripMenuItem_Click(object sender, EventArgs e)
12857 MenuItemUserStream.Enabled = false;
12858 if (StopRefreshAllMenuItem.Checked)
12860 StopRefreshAllMenuItem.Checked = false;
12863 if (this._isActiveUserstream)
12865 tw.StopUserStream();
12869 tw.StartUserStream();
12873 private static string inputTrack = "";
12875 private void TrackToolStripMenuItem_Click(object sender, EventArgs e)
12877 if (TrackToolStripMenuItem.Checked)
12879 using (InputTabName inputForm = new InputTabName())
12881 inputForm.TabName = inputTrack;
12882 inputForm.FormTitle = "Input track word";
12883 inputForm.FormDescription = "Track word";
12884 if (inputForm.ShowDialog() != DialogResult.OK)
12886 TrackToolStripMenuItem.Checked = false;
12889 inputTrack = inputForm.TabName.Trim();
12891 if (!inputTrack.Equals(tw.TrackWord))
12893 tw.TrackWord = inputTrack;
12894 this._modifySettingCommon = true;
12895 TrackToolStripMenuItem.Checked = !string.IsNullOrEmpty(inputTrack);
12896 tw.ReconnectUserStream();
12902 tw.ReconnectUserStream();
12904 this._modifySettingCommon = true;
12907 private void AllrepliesToolStripMenuItem_Click(object sender, EventArgs e)
12909 tw.AllAtReply = AllrepliesToolStripMenuItem.Checked;
12910 this._modifySettingCommon = true;
12911 tw.ReconnectUserStream();
12914 private void EventViewerMenuItem_Click(object sender, EventArgs e)
12916 if (evtDialog == null || evtDialog.IsDisposed)
12919 evtDialog = new EventViewerDialog();
12920 evtDialog.Owner = this;
12922 Point pos = evtDialog.Location;
12923 pos.X = Convert.ToInt32(this.Location.X + this.Size.Width / 2 - evtDialog.Size.Width / 2);
12924 pos.Y = Convert.ToInt32(this.Location.Y + this.Size.Height / 2 - evtDialog.Size.Height / 2);
12925 evtDialog.Location = pos;
12927 evtDialog.EventSource = tw.StoredEvent;
12928 if (!evtDialog.Visible)
12930 evtDialog.Show(this);
12934 evtDialog.Activate();
12936 this.TopMost = this.SettingDialog.AlwaysTop;
12940 private void TweenRestartMenuItem_Click(object sender, EventArgs e)
12942 MyCommon._endingFlag = true;
12946 Application.Restart();
12950 MessageBox.Show("Failed to restart. Please run " + Application.ProductName + " manually.");
12954 private void OpenOwnFavedMenuItem_Click(object sender, EventArgs e)
12956 if (!string.IsNullOrEmpty(tw.Username)) OpenUriAsync(Properties.Resources.FavstarUrl + "users/" + tw.Username + "/recent");
12959 private void OpenOwnHomeMenuItem_Click(object sender, EventArgs e)
12961 OpenUriAsync(MyCommon.TwitterUrl + tw.Username);
12964 private void doTranslation(string str)
12966 Bing _bing = new Bing();
12968 if (string.IsNullOrEmpty(str)) return;
12969 string srclng = "";
12970 string dstlng = SettingDialog.TranslateLanguage;
12972 if (srclng != dstlng && _bing.Translate("", dstlng, str, out buf))
12974 PostBrowser.DocumentText = createDetailHtml(buf);
12978 if (msg.StartsWith("Err:"))
12979 StatusLabel.Text = msg;
12983 private void TranslationToolStripMenuItem_Click(object sender, EventArgs e)
12985 if (!this.ExistCurrentPost) return;
12986 doTranslation(_curPost.TextFromApi);
12989 private void SelectionTranslationToolStripMenuItem_Click(object sender, EventArgs e)
12991 doTranslation(WebBrowser_GetSelectionText(ref PostBrowser));
12994 private bool ExistCurrentPost
12998 if (_curPost == null) return false;
12999 if (_curPost.IsDeleted) return false;
13004 private void ShowUserTimelineToolStripMenuItem_Click(object sender, EventArgs e)
13006 ShowUserTimeline();
13009 public bool FavEventChangeUnread
13011 get { return SettingDialog.FavEventUnread; }
13014 private string GetUserIdFromCurPostOrInput(string caption)
13017 if (_curPost != null)
13019 id = _curPost.ScreenName;
13021 using (InputTabName inputName = new InputTabName())
13023 inputName.FormTitle = caption;
13024 inputName.FormDescription = Properties.Resources.FRMessage1;
13025 inputName.TabName = id;
13026 if (inputName.ShowDialog() == DialogResult.OK &&
13027 !string.IsNullOrEmpty(inputName.TabName.Trim()))
13029 id = inputName.TabName.Trim();
13039 private void UserTimelineToolStripMenuItem_Click(object sender, EventArgs e)
13041 string id = GetUserIdFromCurPostOrInput("Show UserTimeline");
13042 if (!string.IsNullOrEmpty(id))
13044 AddNewTabForUserTimeline(id);
13048 private void UserFavorareToolStripMenuItem_Click(object sender, EventArgs e)
13050 string id = GetUserIdFromCurPostOrInput("Show Favstar");
13051 if (!string.IsNullOrEmpty(id))
13053 OpenUriAsync(Properties.Resources.FavstarUrl + "users/" + id + "/recent");
13057 private void SystemEvents_PowerModeChanged(object sender, Microsoft.Win32.PowerModeChangedEventArgs e)
13059 if (e.Mode == Microsoft.Win32.PowerModes.Resume) osResumed = true;
13062 private void TimelineRefreshEnableChange(bool isEnable)
13066 tw.StartUserStream();
13070 tw.StopUserStream();
13072 TimerTimeline.Enabled = isEnable;
13075 private void StopRefreshAllMenuItem_CheckedChanged(object sender, EventArgs e)
13077 TimelineRefreshEnableChange(!StopRefreshAllMenuItem.Checked);
13080 private void OpenUserAppointUrl()
13082 if (SettingDialog.UserAppointUrl != null)
13084 if (SettingDialog.UserAppointUrl.Contains("{ID}") || SettingDialog.UserAppointUrl.Contains("{STATUS}"))
13086 if (_curPost != null)
13088 string xUrl = SettingDialog.UserAppointUrl;
13089 xUrl = xUrl.Replace("{ID}", _curPost.ScreenName);
13090 if (_curPost.RetweetedId != 0)
13092 xUrl = xUrl.Replace("{STATUS}", _curPost.RetweetedId.ToString());
13096 xUrl = xUrl.Replace("{STATUS}", _curPost.StatusId.ToString());
13098 OpenUriAsync(xUrl);
13103 OpenUriAsync(SettingDialog.UserAppointUrl);
13108 private void OpenUserSpecifiedUrlMenuItem_Click(object sender, EventArgs e)
13110 OpenUserAppointUrl();
13113 private void ImageSelectionPanel_VisibleChanged(object sender, EventArgs e)
13115 this.StatusText_TextChanged(null, null);
13118 private void SourceCopyMenuItem_Click(object sender, EventArgs e)
13120 string selText = SourceLinkLabel.Text;
13123 Clipboard.SetDataObject(selText, false, 5, 100);
13125 catch (Exception ex)
13127 MessageBox.Show(ex.Message);
13131 private void SourceUrlCopyMenuItem_Click(object sender, EventArgs e)
13133 string selText = (string)SourceLinkLabel.Tag;
13136 Clipboard.SetDataObject(selText, false, 5, 100);
13138 catch (Exception ex)
13140 MessageBox.Show(ex.Message);
13144 private void ContextMenuSource_Opening(object sender, CancelEventArgs e)
13146 if (_curPost == null || !ExistCurrentPost || _curPost.IsDm)
13148 SourceCopyMenuItem.Enabled = false;
13149 SourceUrlCopyMenuItem.Enabled = false;
13153 SourceCopyMenuItem.Enabled = true;
13154 SourceUrlCopyMenuItem.Enabled = true;
13158 private void GrowlHelper_Callback(object sender, GrowlHelper.NotifyCallbackEventArgs e)
13160 if (Form.ActiveForm == null)
13162 this.BeginInvoke((Action) (() =>
13164 this.Visible = true;
13165 if (this.WindowState == FormWindowState.Minimized) this.WindowState = FormWindowState.Normal;
13167 this.BringToFront();
13168 if (e.NotifyType == GrowlHelper.NotifyType.DirectMessage)
13170 if (!this.GoDirectMessage(e.StatusId)) this.StatusText.Focus();
13174 if (!this.GoStatus(e.StatusId)) this.StatusText.Focus();
13180 private void ReplaceAppName()
13182 MatomeMenuItem.Text = MyCommon.ReplaceAppName(MatomeMenuItem.Text);
13183 AboutMenuItem.Text = MyCommon.ReplaceAppName(AboutMenuItem.Text);
13186 private void tweetThumbnail1_ThumbnailLoading(object sender, EventArgs e)
13188 this.SplitContainer3.Panel2Collapsed = false;
13191 private void tweetThumbnail1_ThumbnailDoubleClick(object sender, ThumbnailDoubleClickEventArgs e)
13193 this.OpenThumbnailPicture(e.Thumbnail);
13196 private void OpenThumbnailPicture(ThumbnailInfo thumbnail)
13198 this.OpenUriAsync(thumbnail.ImageUrl);