OSDN Git Service

コメントアウトされた不要なコードを削除
[opentween/open-tween.git] / OpenTween / TweetDetailsView.cs
index 9f93253..1b56aa3 100644 (file)
@@ -24,6 +24,8 @@
 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
 // Boston, MA 02110-1301, USA.
 
+#nullable enable
+
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
@@ -39,21 +41,29 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Windows.Forms;
 using OpenTween.Models;
+using OpenTween.Setting;
 
 namespace OpenTween
 {
     public partial class TweetDetailsView : UserControl
     {
-        public TweenMain Owner { get; set; }
+        public TweenMain Owner { get; set; } = null!;
 
         /// <summary>プロフィール画像のキャッシュ</summary>
-        public ImageCache IconCache { get; set; }
+        public ImageCache IconCache { get; set; } = null!;
 
         /// <summary><see cref="PostClass"/> のダンプを表示するか</summary>
         public bool DumpPostClass { get; set; }
 
         /// <summary>現在表示中の発言</summary>
-        public PostClass CurrentPost { get; private set; }
+        public PostClass? CurrentPost { get; private set; }
+
+        [DefaultValue(false)]
+        public new bool TabStop
+        {
+            get => base.TabStop;
+            set => base.TabStop = value;
+        }
 
         /// <summary>ステータスバーに表示するテキストの変化を通知するイベント</summary>
         public event EventHandler<TweetDetailsViewStatusChengedEventArgs> StatusChanged;
@@ -65,6 +75,8 @@ namespace OpenTween
         {
             this.InitializeComponent();
 
+            this.TabStop = false;
+
             //発言詳細部の初期化
             NameLabel.Text = "";
             DateTimeLabel.Text = "";
@@ -83,7 +95,6 @@ namespace OpenTween
             using (ControlTransaction.Update(this.TableLayoutPanel1))
             {
                 SourceLinkLabel.Text = post.Source;
-                SourceLinkLabel.Tag = post.SourceUri;
                 SourceLinkLabel.TabStop = false; // Text を更新すると勝手に true にされる
 
                 string nameText;
@@ -103,44 +114,42 @@ namespace OpenTween
                     nameText += " (RT:" + post.RetweetedBy + ")";
 
                 NameLabel.Text = nameText;
-                NameLabel.Tag = post.ScreenName;
 
                 var nameForeColor = SystemColors.ControlText;
-                if (post.IsOwl && (SettingCommon.Instance.OneWayLove || post.IsDm))
-                    nameForeColor = this.Owner._cfgLocal.ColorOWL;
+                if (post.IsOwl && (SettingManager.Common.OneWayLove || post.IsDm))
+                    nameForeColor = SettingManager.Local.ColorOWL;
                 if (post.RetweetedId != null)
-                    nameForeColor = this.Owner._cfgLocal.ColorRetweet;
+                    nameForeColor = SettingManager.Local.ColorRetweet;
                 if (post.IsFav)
-                    nameForeColor = this.Owner._cfgLocal.ColorFav;
+                    nameForeColor = SettingManager.Local.ColorFav;
                 NameLabel.ForeColor = nameForeColor;
 
                 loadTasks.Add(this.SetUserPictureAsync(post.ImageUrl));
 
-                DateTimeLabel.Text = post.CreatedAt.ToString();
+                DateTimeLabel.Text = post.CreatedAt.ToLocalTimeString();
             }
 
             if (this.DumpPostClass)
             {
-                StringBuilder sb = new StringBuilder(512);
+                var sb = new StringBuilder(512);
 
                 sb.Append("-----Start PostClass Dump<br>");
                 sb.AppendFormat("TextFromApi           : {0}<br>", post.TextFromApi);
                 sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", post.TextFromApi);
-                sb.AppendFormat("StatusId             : {0}<br>", post.StatusId.ToString());
-                //sb.AppendFormat("ImageIndex     : {0}<br>", post.ImageIndex.ToString());
+                sb.AppendFormat("StatusId             : {0}<br>", post.StatusId);
                 sb.AppendFormat("ImageUrl       : {0}<br>", post.ImageUrl);
-                sb.AppendFormat("InReplyToStatusId    : {0}<br>", post.InReplyToStatusId.ToString());
+                sb.AppendFormat("InReplyToStatusId    : {0}<br>", post.InReplyToStatusId);
                 sb.AppendFormat("InReplyToUser  : {0}<br>", post.InReplyToUser);
-                sb.AppendFormat("IsDM           : {0}<br>", post.IsDm.ToString());
-                sb.AppendFormat("IsFav          : {0}<br>", post.IsFav.ToString());
-                sb.AppendFormat("IsMark         : {0}<br>", post.IsMark.ToString());
-                sb.AppendFormat("IsMe           : {0}<br>", post.IsMe.ToString());
-                sb.AppendFormat("IsOwl          : {0}<br>", post.IsOwl.ToString());
-                sb.AppendFormat("IsProtect      : {0}<br>", post.IsProtect.ToString());
-                sb.AppendFormat("IsRead         : {0}<br>", post.IsRead.ToString());
-                sb.AppendFormat("IsReply        : {0}<br>", post.IsReply.ToString());
-
-                foreach (string nm in post.ReplyToList)
+                sb.AppendFormat("IsDM           : {0}<br>", post.IsDm);
+                sb.AppendFormat("IsFav          : {0}<br>", post.IsFav);
+                sb.AppendFormat("IsMark         : {0}<br>", post.IsMark);
+                sb.AppendFormat("IsMe           : {0}<br>", post.IsMe);
+                sb.AppendFormat("IsOwl          : {0}<br>", post.IsOwl);
+                sb.AppendFormat("IsProtect      : {0}<br>", post.IsProtect);
+                sb.AppendFormat("IsRead         : {0}<br>", post.IsRead);
+                sb.AppendFormat("IsReply        : {0}<br>", post.IsReply);
+
+                foreach (var nm in post.ReplyToList.Select(x => x.ScreenName))
                 {
                     sb.AppendFormat("ReplyToList    : {0}<br>", nm);
                 }
@@ -149,7 +158,7 @@ namespace OpenTween
                 sb.AppendFormat("NickName       : {0}<br>", post.Nickname);
                 sb.AppendFormat("Text   : {0}<br>", post.Text);
                 sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", post.Text);
-                sb.AppendFormat("CreatedAt          : {0}<br>", post.CreatedAt.ToString());
+                sb.AppendFormat("CreatedAt          : {0}<br>", post.CreatedAt.ToLocalTimeString());
                 sb.AppendFormat("Source         : {0}<br>", post.Source);
                 sb.AppendFormat("UserId            : {0}<br>", post.UserId);
                 sb.AppendFormat("FilterHit      : {0}<br>", post.FilterHit);
@@ -159,7 +168,7 @@ namespace OpenTween
                 sb.AppendFormat("Media.Count    : {0}<br>", post.Media.Count);
                 if (post.Media.Count > 0)
                 {
-                    for (int i = 0; i < post.Media.Count; i++)
+                    for (var i = 0; i < post.Media.Count; i++)
                     {
                         var info = post.Media[i];
                         sb.AppendFormat("Media[{0}].Url         : {1}<br>", i, info.Url);
@@ -194,9 +203,9 @@ namespace OpenTween
             if (tags.Count > 0)
             {
                 if (forward)
-                    tags[0].ScrollTop += this.Owner._cfgLocal.FontDetail.Height;
+                    tags[0].ScrollTop += SettingManager.Local.FontDetail.Height;
                 else
-                    tags[0].ScrollTop -= this.Owner._cfgLocal.FontDetail.Height;
+                    tags[0].ScrollTop -= SettingManager.Local.FontDetail.Height;
             }
         }
 
@@ -209,9 +218,9 @@ namespace OpenTween
             if (tags.Count > 0)
             {
                 if (forward)
-                    tags[0].ScrollTop += PostBrowser.ClientRectangle.Height - this.Owner._cfgLocal.FontDetail.Height;
+                    tags[0].ScrollTop += PostBrowser.ClientRectangle.Height - SettingManager.Local.FontDetail.Height;
                 else
-                    tags[0].ScrollTop -= PostBrowser.ClientRectangle.Height - this.Owner._cfgLocal.FontDetail.Height;
+                    tags[0].ScrollTop -= PostBrowser.ClientRectangle.Height - SettingManager.Local.FontDetail.Height;
             }
         }
 
@@ -322,7 +331,7 @@ namespace OpenTween
             var innerHtml = "<p>" + StripLinkTagHtml(post.Text) + "</p>" +
                 " &mdash; " + WebUtility.HtmlEncode(post.Nickname) +
                 " (@" + WebUtility.HtmlEncode(post.ScreenName) + ") " +
-                WebUtility.HtmlEncode(post.CreatedAt.ToString());
+                WebUtility.HtmlEncode(post.CreatedAt.ToLocalTimeString());
 
             return FormatQuoteTweetHtml(post.StatusId, innerHtml, isReply);
         }
@@ -343,10 +352,7 @@ namespace OpenTween
         /// 指定されたHTMLからリンクを除去します
         /// </summary>
         internal static string StripLinkTagHtml(string html)
-        {
-            // a 要素はネストされていない前提の正規表現パターン
-            return Regex.Replace(html, @"<a[^>]*>(.*?)</a>", "$1");
-        }
+            => Regex.Replace(html, @"<a[^>]*>(.*?)</a>", "$1"); // a 要素はネストされていない前提の正規表現パターン
 
         public async Task DoTranslation()
         {
@@ -366,7 +372,7 @@ namespace OpenTween
             {
                 var translatedText = await bing.TranslateAsync(str,
                     langFrom: null,
-                    langTo: SettingCommon.Instance.TranslateLanguage);
+                    langTo: SettingManager.Common.TranslateLanguage);
 
                 this.PostBrowser.DocumentText = this.Owner.createDetailHtml(translatedText);
             }
@@ -383,7 +389,7 @@ namespace OpenTween
         private async Task DoSearchToolStrip(string url)
         {
             //発言詳細で「選択文字列で検索」(選択文字列取得)
-            string _selText = this.PostBrowser.GetSelectedText();
+            var _selText = this.PostBrowser.GetSelectedText();
 
             if (_selText != null)
             {
@@ -394,14 +400,14 @@ namespace OpenTween
                     return;
                 }
 
-                string tmp = string.Format(url, Uri.EscapeDataString(_selText));
+                var tmp = string.Format(url, Uri.EscapeDataString(_selText));
                 await this.Owner.OpenUriInBrowserAsync(tmp);
             }
         }
 
-        private string GetUserId()
+        private string? GetUserId()
         {
-            Match m = Regex.Match(this._postBrowserStatusText, @"^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?$");
+            var m = Regex.Match(this._postBrowserStatusText, @"^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?$");
             if (m.Success && this.Owner.IsTwitterId(m.Result("${ScreenName}")))
                 return m.Result("${ScreenName}");
             else
@@ -409,35 +415,36 @@ namespace OpenTween
         }
 
         protected void RaiseStatusChanged(string statusText)
+            => this.StatusChanged?.Invoke(this, new TweetDetailsViewStatusChengedEventArgs(statusText));
+
+        private void TweetDetailsView_FontChanged(object sender, EventArgs e)
         {
-            this.StatusChanged?.Invoke(this, new TweetDetailsViewStatusChengedEventArgs(statusText));
+            // OTBaseForm.GlobalFont による UI フォントの変更に対応
+            var origFont = this.NameLabel.Font;
+            this.NameLabel.Font = new Font(this.Font.Name, origFont.Size, origFont.Style);
         }
 
         #region TableLayoutPanel1
 
         private async void UserPicture_DoubleClick(object sender, EventArgs e)
         {
-            if (NameLabel.Tag != null)
-            {
-                await this.Owner.OpenUriInBrowserAsync(MyCommon.TwitterUrl + NameLabel.Tag.ToString());
-            }
+            if (this.CurrentPost == null)
+                return;
+
+            await this.Owner.OpenUriInBrowserAsync(MyCommon.TwitterUrl + this.CurrentPost.ScreenName);
         }
 
         private void UserPicture_MouseEnter(object sender, EventArgs e)
-        {
-            this.UserPicture.Cursor = Cursors.Hand;
-        }
+            => this.UserPicture.Cursor = Cursors.Hand;
 
         private void UserPicture_MouseLeave(object sender, EventArgs e)
-        {
-            this.UserPicture.Cursor = Cursors.Default;
-        }
+            => this.UserPicture.Cursor = Cursors.Default;
 
         private async void PostBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
         {
             if (e.Url.AbsoluteUri != "about:blank")
             {
-                await this.ShowPostDetails(this.CurrentPost); // 現在の発言を表示し直す (Navigated の段階ではキャンセルできない)
+                await this.ShowPostDetails(this.CurrentPost!); // 現在の発言を表示し直す (Navigated の段階ではキャンセルできない)
                 await this.Owner.OpenUriInBrowserAsync(e.Url.OriginalString);
             }
         }
@@ -458,8 +465,7 @@ namespace OpenTween
 
         private async void PostBrowser_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
         {
-            Task asyncTask;
-            bool KeyRes = this.Owner.CommonKeyDown(e.KeyData, FocusedControl.PostBrowser, out asyncTask);
+            var KeyRes = this.Owner.CommonKeyDown(e.KeyData, FocusedControl.PostBrowser, out var asyncTask);
             if (KeyRes)
             {
                 e.IsInputKey = true;
@@ -510,7 +516,7 @@ namespace OpenTween
 
         private async void SourceLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
         {
-            var sourceUri = (Uri)this.SourceLinkLabel.Tag;
+            var sourceUri = this.CurrentPost?.SourceUri;
             if (sourceUri != null && e.Button == MouseButtons.Left)
             {
                 await this.Owner.OpenUriInBrowserAsync(sourceUri.AbsoluteUri);
@@ -519,7 +525,7 @@ namespace OpenTween
 
         private void SourceLinkLabel_MouseEnter(object sender, EventArgs e)
         {
-            var sourceUri = (Uri)this.SourceLinkLabel.Tag;
+            var sourceUri = this.CurrentPost?.SourceUri;
             if (sourceUri != null)
             {
                 this.RaiseStatusChanged(MyCommon.ConvertToReadableUrl(sourceUri.AbsoluteUri));
@@ -527,9 +533,7 @@ namespace OpenTween
         }
 
         private void SourceLinkLabel_MouseLeave(object sender, EventArgs e)
-        {
-            this.RaiseStatusChanged(statusText: "");
-        }
+            => this.RaiseStatusChanged(statusText: "");
 
         #endregion
 
@@ -540,10 +544,10 @@ namespace OpenTween
             //発言詳細のアイコン右クリック時のメニュー制御
             if (this.CurrentPost != null)
             {
-                string name = this.CurrentPost.ImageUrl;
-                if (name != null && name.Length > 0)
+                var name = this.CurrentPost.ImageUrl;
+                if (!string.IsNullOrEmpty(name))
                 {
-                    int idx = name.LastIndexOf('/');
+                    var idx = name.LastIndexOf('/');
                     if (idx != -1)
                     {
                         name = Path.GetFileName(name.Substring(idx));
@@ -591,10 +595,9 @@ namespace OpenTween
                 this.SaveIconPictureToolStripMenuItem.Enabled = false;
                 this.IconNameToolStripMenuItem.Text = Properties.Resources.ContextMenuStrip3_OpeningText2;
             }
-            if (NameLabel.Tag != null)
+            if (this.CurrentPost != null)
             {
-                string id = (string)NameLabel.Tag;
-                if (id == this.Owner.TwitterInstance.Username)
+                if (this.CurrentPost.UserId == this.Owner.TwitterInstance.UserId)
                 {
                     FollowToolStripMenuItem.Enabled = false;
                     UnFollowToolStripMenuItem.Enabled = false;
@@ -629,67 +632,61 @@ namespace OpenTween
 
         private async void FollowToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            if (NameLabel.Tag != null)
-            {
-                string id = (string)NameLabel.Tag;
-                if (id != this.Owner.TwitterInstance.Username)
-                {
-                    await this.Owner.FollowCommand(id);
-                }
-            }
+            if (this.CurrentPost == null)
+                return;
+
+            if (this.CurrentPost.UserId == this.Owner.TwitterInstance.UserId)
+                return;
+
+            await this.Owner.FollowCommand(this.CurrentPost.ScreenName);
         }
 
         private async void UnFollowToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            if (NameLabel.Tag != null)
-            {
-                string id = (string)NameLabel.Tag;
-                if (id != this.Owner.TwitterInstance.Username)
-                {
-                    await this.Owner.RemoveCommand(id, false);
-                }
-            }
+            if (this.CurrentPost == null)
+                return;
+
+            if (this.CurrentPost.UserId == this.Owner.TwitterInstance.UserId)
+                return;
+
+            await this.Owner.RemoveCommand(this.CurrentPost.ScreenName, false);
         }
 
         private async void ShowFriendShipToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            if (NameLabel.Tag != null)
-            {
-                string id = (string)NameLabel.Tag;
-                if (id != this.Owner.TwitterInstance.Username)
-                {
-                    await this.Owner.ShowFriendship(id);
-                }
-            }
+            if (this.CurrentPost == null)
+                return;
+
+            if (this.CurrentPost.UserId == this.Owner.TwitterInstance.UserId)
+                return;
+
+            await this.Owner.ShowFriendship(this.CurrentPost.ScreenName);
         }
 
         // ListManageUserContextToolStripMenuItem3.Click は ListManageUserContextToolStripMenuItem_Click を共用
 
         private async void ShowUserStatusToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            if (NameLabel.Tag != null)
-            {
-                string id = (string)NameLabel.Tag;
-                await this.Owner.ShowUserStatus(id, false);
-            }
+            if (this.CurrentPost == null)
+                return;
+
+            await this.Owner.ShowUserStatus(this.CurrentPost.ScreenName, false);
         }
 
-        private void SearchPostsDetailNameToolStripMenuItem_Click(object sender, EventArgs e)
+        private async void SearchPostsDetailNameToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            if (NameLabel.Tag != null)
-            {
-                string id = (string)NameLabel.Tag;
-                this.Owner.AddNewTabForUserTimeline(id);
-            }
+            if (this.CurrentPost == null)
+                return;
+
+            await this.Owner.AddNewTabForUserTimeline(this.CurrentPost.ScreenName);
         }
 
         private void SearchAtPostsDetailNameToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            if (NameLabel.Tag != null)
-            {
-                string id = (string)NameLabel.Tag;
-                this.Owner.AddNewTabForSearch("@" + id);
-            }
+            if (this.CurrentPost == null)
+                return;
+
+            this.Owner.AddNewTabForSearch("@" + this.CurrentPost.ScreenName);
         }
 
         private async void IconNameToolStripMenuItem_Click(object sender, EventArgs e)
@@ -698,7 +695,7 @@ namespace OpenTween
             if (string.IsNullOrEmpty(imageUrl))
                 return;
 
-            await this.Owner.OpenUriInBrowserAsync(imageUrl.Remove(imageUrl.LastIndexOf("_normal"), 7)); // "_normal".Length
+            await this.Owner.OpenUriInBrowserAsync(imageUrl.Remove(imageUrl.LastIndexOf("_normal", StringComparison.Ordinal), 7)); // "_normal".Length
         }
 
         private async void ReloadIconToolStripMenuItem_Click(object sender, EventArgs e)
@@ -716,24 +713,25 @@ namespace OpenTween
             if (string.IsNullOrEmpty(imageUrl))
                 return;
 
+            var memoryImage = this.IconCache.TryGetFromCache(imageUrl);
+            if (memoryImage == null)
+                return;
+
             this.Owner.SaveFileDialog1.FileName = imageUrl.Substring(imageUrl.LastIndexOf('/') + 1);
 
             if (this.Owner.SaveFileDialog1.ShowDialog() == DialogResult.OK)
             {
                 try
                 {
-                    using (Image orgBmp = new Bitmap(IconCache.TryGetFromCache(imageUrl).Image))
+                    using var orgBmp = new Bitmap(memoryImage.Image);
+                    using var bmp2 = new Bitmap(orgBmp.Size.Width, orgBmp.Size.Height);
+
+                    using (var g = Graphics.FromImage(bmp2))
                     {
-                        using (Bitmap bmp2 = new Bitmap(orgBmp.Size.Width, orgBmp.Size.Height))
-                        {
-                            using (Graphics g = Graphics.FromImage(bmp2))
-                            {
-                                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
-                                g.DrawImage(orgBmp, 0, 0, orgBmp.Size.Width, orgBmp.Size.Height);
-                            }
-                            bmp2.Save(this.Owner.SaveFileDialog1.FileName);
-                        }
+                        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
+                        g.DrawImage(orgBmp, 0, 0, orgBmp.Size.Width, orgBmp.Size.Height);
                     }
+                    bmp2.Save(this.Owner.SaveFileDialog1.FileName);
                 }
                 catch (Exception)
                 {
@@ -752,7 +750,7 @@ namespace OpenTween
             if (PostBrowser.StatusText.StartsWith("http", StringComparison.Ordinal))
             {
                 this._postBrowserStatusText = PostBrowser.StatusText;
-                string name = GetUserId();
+                var name = GetUserId();
                 UrlCopyContextMenuItem.Enabled = true;
                 if (name != null)
                 {
@@ -797,7 +795,7 @@ namespace OpenTween
                 ListManageUserContextToolStripMenuItem.Enabled = false;
             }
             // 文字列選択されていないときは選択文字列関係の項目を非表示に
-            string _selText = this.PostBrowser.GetSelectedText();
+            var _selText = this.PostBrowser.GetSelectedText();
             if (_selText == null)
             {
                 SelectionSearchContextMenuItem.Enabled = false;
@@ -811,11 +809,11 @@ namespace OpenTween
                 SelectionTranslationToolStripMenuItem.Enabled = true;
             }
             //発言内に自分以外のユーザーが含まれてればフォロー状態全表示を有効に
-            MatchCollection ma = Regex.Matches(this.PostBrowser.DocumentText, @"href=""https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?""");
-            bool fAllFlag = false;
+            var ma = Regex.Matches(this.PostBrowser.DocumentText, @"href=""https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?""");
+            var fAllFlag = false;
             foreach (Match mu in ma)
             {
-                if (mu.Result("${ScreenName}").ToLowerInvariant() != this.Owner.TwitterInstance.Username.ToLowerInvariant())
+                if (!mu.Result("${ScreenName}").Equals(this.Owner.TwitterInstance.Username, StringComparison.InvariantCultureIgnoreCase))
                 {
                     fAllFlag = true;
                     break;
@@ -832,24 +830,18 @@ namespace OpenTween
         }
 
         private async void SearchGoogleContextMenuItem_Click(object sender, EventArgs e)
-        {
-            await this.DoSearchToolStrip(Properties.Resources.SearchItem2Url);
-        }
+            => await this.DoSearchToolStrip(Properties.Resources.SearchItem2Url);
 
         private async void SearchWikipediaContextMenuItem_Click(object sender, EventArgs e)
-        {
-            await this.DoSearchToolStrip(Properties.Resources.SearchItem1Url);
-        }
+            => await this.DoSearchToolStrip(Properties.Resources.SearchItem1Url);
 
         private async void SearchPublicSearchContextMenuItem_Click(object sender, EventArgs e)
-        {
-            await this.DoSearchToolStrip(Properties.Resources.SearchItem4Url);
-        }
+            => await this.DoSearchToolStrip(Properties.Resources.SearchItem4Url);
 
         private void CurrentTabToolStripMenuItem_Click(object sender, EventArgs e)
         {
             //発言詳細の選択文字列で現在のタブを検索
-            string _selText = this.PostBrowser.GetSelectedText();
+            var _selText = this.PostBrowser.GetSelectedText();
 
             if (_selText != null)
             {
@@ -873,7 +865,7 @@ namespace OpenTween
         private void SelectionCopyContextMenuItem_Click(object sender, EventArgs e)
         {
             //発言詳細で「選択文字列をコピー」
-            string _selText = this.PostBrowser.GetSelectedText();
+            var _selText = this.PostBrowser.GetSelectedText();
             try
             {
                 Clipboard.SetDataObject(_selText, false, 5, 100);
@@ -910,39 +902,36 @@ namespace OpenTween
         }
 
         private void SelectionAllContextMenuItem_Click(object sender, EventArgs e)
-        {
-            //発言詳細ですべて選択
-            PostBrowser.Document.ExecCommand("SelectAll", false, null);
-        }
+            => this.PostBrowser.Document.ExecCommand("SelectAll", false, null); // 発言詳細ですべて選択
 
         private async void FollowContextMenuItem_Click(object sender, EventArgs e)
         {
-            string name = GetUserId();
+            var name = GetUserId();
             if (name != null)
                 await this.Owner.FollowCommand(name);
         }
 
         private async void RemoveContextMenuItem_Click(object sender, EventArgs e)
         {
-            string name = GetUserId();
+            var name = GetUserId();
             if (name != null)
                 await this.Owner.RemoveCommand(name, false);
         }
 
         private async void FriendshipContextMenuItem_Click(object sender, EventArgs e)
         {
-            string name = GetUserId();
+            var name = GetUserId();
             if (name != null)
                 await this.Owner.ShowFriendship(name);
         }
 
         private async void FriendshipAllMenuItem_Click(object sender, EventArgs e)
         {
-            MatchCollection ma = Regex.Matches(this.PostBrowser.DocumentText, @"href=""https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?""");
-            List<string> ids = new List<string>();
+            var ma = Regex.Matches(this.PostBrowser.DocumentText, @"href=""https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?""");
+            var ids = new List<string>();
             foreach (Match mu in ma)
             {
-                if (mu.Result("${ScreenName}").ToLower() != this.Owner.TwitterInstance.Username.ToLower())
+                if (!mu.Result("${ScreenName}").Equals(this.Owner.TwitterInstance.Username, StringComparison.InvariantCultureIgnoreCase))
                 {
                     ids.Add(mu.Result("${ScreenName}"));
                 }
@@ -953,35 +942,36 @@ namespace OpenTween
 
         private async void ShowUserStatusContextMenuItem_Click(object sender, EventArgs e)
         {
-            string name = GetUserId();
+            var name = GetUserId();
             if (name != null)
                 await this.Owner.ShowUserStatus(name);
         }
 
-        private void SearchPostsDetailToolStripMenuItem_Click(object sender, EventArgs e)
+        private async void SearchPostsDetailToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            string name = GetUserId();
-            if (name != null) this.Owner.AddNewTabForUserTimeline(name);
+            var name = GetUserId();
+            if (name != null)
+                await this.Owner.AddNewTabForUserTimeline(name);
         }
 
         private void SearchAtPostsDetailToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            string name = GetUserId();
+            var name = GetUserId();
             if (name != null) this.Owner.AddNewTabForSearch("@" + name);
         }
 
         private void IdFilterAddMenuItem_Click(object sender, EventArgs e)
         {
-            string name = GetUserId();
+            var name = GetUserId();
             if (name != null)
                 this.Owner.AddFilterRuleByScreenName(name);
         }
 
-        private async void ListManageUserContextToolStripMenuItem_Click(object sender, EventArgs e)
+        private void ListManageUserContextToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            ToolStripMenuItem menuItem = (ToolStripMenuItem)sender;
+            var menuItem = (ToolStripMenuItem)sender;
 
-            string user;
+            string? user;
             if (menuItem.Owner == this.ContextMenuPostBrowser)
             {
                 user = GetUserId();
@@ -996,12 +986,12 @@ namespace OpenTween
                 return;
             }
 
-            await this.Owner.ListManageUserContext(user);
+            this.Owner.ListManageUserContext(user);
         }
 
         private void UseHashtagMenuItem_Click(object sender, EventArgs e)
         {
-            Match m = Regex.Match(this._postBrowserStatusText, @"^https?://twitter.com/search\?q=%23(?<hash>.+)$");
+            var m = Regex.Match(this._postBrowserStatusText, @"^https?://twitter.com/search\?q=%23(?<hash>.+)$");
             if (m.Success)
                 this.Owner.SetPermanentHashtag(Uri.UnescapeDataString(m.Groups["hash"].Value));
         }
@@ -1013,9 +1003,7 @@ namespace OpenTween
         }
 
         private async void TranslationToolStripMenuItem_Click(object sender, EventArgs e)
-        {
-            await this.DoTranslation();
-        }
+            => await this.DoTranslation();
 
         #endregion
 
@@ -1037,10 +1025,12 @@ namespace OpenTween
 
         private void SourceCopyMenuItem_Click(object sender, EventArgs e)
         {
-            string selText = SourceLinkLabel.Text;
+            if (this.CurrentPost == null)
+                return;
+
             try
             {
-                Clipboard.SetDataObject(selText, false, 5, 100);
+                Clipboard.SetDataObject(this.CurrentPost.Source, false, 5, 100);
             }
             catch (Exception ex)
             {
@@ -1050,7 +1040,10 @@ namespace OpenTween
 
         private void SourceUrlCopyMenuItem_Click(object sender, EventArgs e)
         {
-            var sourceUri = (Uri)this.SourceLinkLabel.Tag;
+            var sourceUri = this.CurrentPost?.SourceUri;
+            if (sourceUri == null)
+                return;
+
             try
             {
                 Clipboard.SetDataObject(sourceUri.AbsoluteUri, false, 5, 100);
@@ -1073,8 +1066,6 @@ namespace OpenTween
         public string StatusText { get; }
 
         public TweetDetailsViewStatusChengedEventArgs(string statusText)
-        {
-            this.StatusText = statusText;
-        }
+            => this.StatusText = statusText;
     }
 }