Пример #1
0
        private void DispSelectedPost(bool forceupdate)
        {
            if (_curList.SelectedIndices.Count == 0 || _curPost == null)
                return;

            if (!forceupdate && _curPost.Equals(displaypost))
                return;

            displaypost = _curPost;
            if (displayItem != null)
            {
                displayItem.ImageDownloaded -= this.DisplayItemImage_Downloaded;
                displayItem = null;
            }
            displayItem = (ImageListViewItem)_curList.Items[_curList.SelectedIndices[0]];
            displayItem.ImageDownloaded += this.DisplayItemImage_Downloaded;

            string dTxt = createDetailHtml(_curPost.IsDeleted ? "(DELETED)" : _curPost.Text);
            if (_curPost.IsDm)
            {
                SourceLinkLabel.Tag = null;
                SourceLinkLabel.Text = "";
            }
            else
            {
                Match mc = Regex.Match(_curPost.SourceHtml, "<a href=\"(?<sourceurl>.+?)\"");
                if (mc.Success)
                {
                    string src = mc.Groups["sourceurl"].Value;
                    SourceLinkLabel.Tag = mc.Groups["sourceurl"].Value;
                    mc = Regex.Match(src, "^https?://");
                    if (!mc.Success)
                    {
                        src = src.Insert(0, "http://twitter.com");
                    }
                    SourceLinkLabel.Tag = src;
                }
                else
                {
                    SourceLinkLabel.Tag = null;
                }
                if (string.IsNullOrEmpty(_curPost.Source))
                {
                    SourceLinkLabel.Text = "";
                    //SourceLinkLabel.Visible = false;
                }
                else
                {
                    SourceLinkLabel.Text = _curPost.Source;
                    //SourceLinkLabel.Visible = true;
                }
            }
            SourceLinkLabel.TabStop = false;

            if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage && !_curPost.IsOwl)
            {
                NameLabel.Text = "DM TO -> ";
            }
            else if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage)
            {
                NameLabel.Text = "DM FROM <- ";
            }
            else
            {
                NameLabel.Text = "";
            }
            NameLabel.Text += _curPost.ScreenName + "/" + _curPost.Nickname;
            NameLabel.Tag = _curPost.ScreenName;
            if (!string.IsNullOrEmpty(_curPost.RetweetedBy))
            {
                NameLabel.Text += " (RT:" + _curPost.RetweetedBy + ")";
            }
            if (UserPicture.Image != null) UserPicture.Image.Dispose();
            if (!string.IsNullOrEmpty(_curPost.ImageUrl) && TIconDic[_curPost.ImageUrl] != null)
            {
                try
                {
                    UserPicture.Image = new Bitmap(TIconDic[_curPost.ImageUrl]);
                }
                catch (Exception)
                {
                    UserPicture.Image = null;
                }
            }
            else
            {
                UserPicture.Image = null;
            }

            NameLabel.ForeColor = System.Drawing.SystemColors.ControlText;
            DateTimeLabel.Text = _curPost.CreatedAt.ToString();
            if (_curPost.IsOwl && (SettingDialog.OneWayLove || _statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage)) NameLabel.ForeColor = _clOWL;
            if (_curPost.RetweetedId > 0) NameLabel.ForeColor = _clRetweet;
            if (_curPost.IsFav) NameLabel.ForeColor = _clFav;

            if (DumpPostClassToolStripMenuItem.Checked)
            {
                StringBuilder sb = new StringBuilder(512);

                sb.Append("-----Start PostClass Dump<br>");
                sb.AppendFormat("TextFromApi           : {0}<br>", _curPost.TextFromApi);
                sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.TextFromApi);
                sb.AppendFormat("StatusId             : {0}<br>", _curPost.StatusId.ToString());
                //sb.AppendFormat("ImageIndex     : {0}<br>", _curPost.ImageIndex.ToString());
                sb.AppendFormat("ImageUrl       : {0}<br>", _curPost.ImageUrl);
                sb.AppendFormat("InReplyToStatusId    : {0}<br>", _curPost.InReplyToStatusId.ToString());
                sb.AppendFormat("InReplyToUser  : {0}<br>", _curPost.InReplyToUser);
                sb.AppendFormat("IsDM           : {0}<br>", _curPost.IsDm.ToString());
                sb.AppendFormat("IsFav          : {0}<br>", _curPost.IsFav.ToString());
                sb.AppendFormat("IsMark         : {0}<br>", _curPost.IsMark.ToString());
                sb.AppendFormat("IsMe           : {0}<br>", _curPost.IsMe.ToString());
                sb.AppendFormat("IsOwl          : {0}<br>", _curPost.IsOwl.ToString());
                sb.AppendFormat("IsProtect      : {0}<br>", _curPost.IsProtect.ToString());
                sb.AppendFormat("IsRead         : {0}<br>", _curPost.IsRead.ToString());
                sb.AppendFormat("IsReply        : {0}<br>", _curPost.IsReply.ToString());

                foreach (string nm in _curPost.ReplyToList)
                {
                    sb.AppendFormat("ReplyToList    : {0}<br>", nm);
                }

                sb.AppendFormat("ScreenName           : {0}<br>", _curPost.ScreenName);
                sb.AppendFormat("NickName       : {0}<br>", _curPost.Nickname);
                sb.AppendFormat("Text   : {0}<br>", _curPost.Text);
                sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.Text);
                sb.AppendFormat("CreatedAt          : {0}<br>", _curPost.CreatedAt.ToString());
                sb.AppendFormat("Source         : {0}<br>", _curPost.Source);
                sb.AppendFormat("UserId            : {0}<br>", _curPost.UserId);
                sb.AppendFormat("FilterHit      : {0}<br>", _curPost.FilterHit);
                sb.AppendFormat("RetweetedBy    : {0}<br>", _curPost.RetweetedBy);
                sb.AppendFormat("RetweetedId    : {0}<br>", _curPost.RetweetedId);
                sb.AppendFormat("SearchTabName  : {0}<br>", _curPost.RelTabName);
                sb.Append("-----End PostClass Dump<br>");

                PostBrowser.Visible = false;
                PostBrowser.DocumentText = detailHtmlFormatHeader + sb.ToString() + detailHtmlFormatFooter;
                PostBrowser.Visible = true;
            }
            else
            {
                try
                {
                    if (PostBrowser.DocumentText != dTxt)
                    {
                        PostBrowser.Visible = false;
                        PostBrowser.DocumentText = dTxt;
                        List<string> lnks = new List<string>();
                        foreach (Match lnk in Regex.Matches(dTxt, "<a target=\"_self\" href=\"(?<url>http[^\"]+)\"", RegexOptions.IgnoreCase))
                        {
                            lnks.Add(lnk.Result("${url}"));
                        }
                        Thumbnail.thumbnail(_curPost.StatusId, lnks, _curPost.PostGeo, _curPost.Media);
                    }
                }
                catch (System.Runtime.InteropServices.COMException)
                {
                    //原因不明
                }
                catch (UriFormatException)
                {
                    PostBrowser.DocumentText = dTxt;
                }
                finally
                {
                    PostBrowser.Visible = true;
                }
            }
        }
Пример #2
0
        private ListViewItem CreateItem(TabPage Tab, PostClass Post, int Index)
        {
            StringBuilder mk = new StringBuilder();
            //if (Post.IsDeleted) mk.Append("×");
            //if (Post.IsMark) mk.Append("♪");
            //if (Post.IsProtect) mk.Append("Ю");
            //if (Post.InReplyToStatusId > 0) mk.Append("⇒");
            if (Post.FavoritedCount > 0) mk.Append("+" + Post.FavoritedCount.ToString());
            ImageListViewItem itm;
            if (Post.RetweetedId == 0)
            {
                string[] sitem= {"",
                                 Post.Nickname,
                                 Post.IsDeleted ? "(DELETED)" : Post.TextFromApi,
                                 Post.CreatedAt.ToString(SettingDialog.DateTimeFormat),
                                 Post.ScreenName,
                                 "",
                                 mk.ToString(),
                                 Post.Source};
                itm = new ImageListViewItem(sitem, (ImageDictionary)this.TIconDic, Post.ImageUrl);
            }
            else
            {
                string[] sitem = {"",
                                  Post.Nickname,
                                  Post.IsDeleted ? "(DELETED)" : Post.TextFromApi,
                                  Post.CreatedAt.ToString(SettingDialog.DateTimeFormat),
                                  Post.ScreenName + Environment.NewLine + "(RT:" + Post.RetweetedBy + ")",
                                  "",
                                  mk.ToString(),
                                  Post.Source};
                itm = new ImageListViewItem(sitem, (ImageDictionary)this.TIconDic, Post.ImageUrl);
            }
            itm.StateImageIndex = Post.StateIndex;

            bool read = Post.IsRead;
            //未読管理していなかったら既読として扱う
            if (!_statuses.Tabs[Tab.Text].UnreadManage || !SettingDialog.UnreadManage) read = true;
            ChangeItemStyleRead(read, itm, Post, null);
            if (Tab.Equals(_curTab)) ColorizeList(itm, Index);
            return itm;
        }
Пример #3
0
        private void DispSelectedPost(bool forceupdate)
        {
            if (_curList.SelectedIndices.Count == 0 || _curPost == null)
                return;

            var oldDisplayPost = this.displayPost;
            this.displayPost = this._curPost;

            if (!forceupdate && this._curPost.Equals(oldDisplayPost))
                return;

            if (displayItem != null)
            {
                displayItem.ImageDownloaded -= this.DisplayItemImage_Downloaded;
                displayItem = null;
            }
            displayItem = (ImageListViewItem)_curList.Items[_curList.SelectedIndices[0]];
            displayItem.ImageDownloaded += this.DisplayItemImage_Downloaded;

            using (ControlTransaction.Update(this.TableLayoutPanel1))
            {
                var sourceText = "";
                string sourceUrl = null;
                if (!_curPost.IsDm)
                {
                    var mc = Regex.Match(_curPost.SourceHtml, "<a href=\"(?<sourceurl>.+?)\"");
                    if (mc.Success)
                    {
                        var src = mc.Groups["sourceurl"].Value;
                        if (Regex.IsMatch(src, "^https?://"))
                            sourceUrl = src;
                        else
                            sourceUrl = "https://twitter.com/" + src;
                    }

                    if (_curPost.Source != null)
                        sourceText = _curPost.Source;
                }
                SourceLinkLabel.Text = sourceText;
                SourceLinkLabel.Tag = sourceUrl;
                SourceLinkLabel.TabStop = false; // Text を更新すると勝手に true にされる

                string nameText;
                if (_curPost.IsDm)
                {
                    if (_curPost.IsOwl)
                        nameText = "DM FROM <- ";
                    else
                        nameText = "DM TO -> ";
                }
                else
                {
                    nameText = "";
                }
                nameText += _curPost.ScreenName + "/" + _curPost.Nickname;
                if (_curPost.RetweetedId != null)
                    nameText += " (RT:" + _curPost.RetweetedBy + ")";

                NameLabel.Text = nameText;
                NameLabel.Tag = _curPost.ScreenName;

                var nameForeColor = SystemColors.ControlText;
                if (_curPost.IsOwl && (this._cfgCommon.OneWayLove || _curPost.IsDm))
                    nameForeColor = this._clOWL;
                if (_curPost.RetweetedId != null)
                    nameForeColor = this._clRetweet;
                if (_curPost.IsFav)
                    nameForeColor = this._clFav;
                NameLabel.ForeColor = nameForeColor;

                this.ClearUserPicture();

                if (!string.IsNullOrEmpty(_curPost.ImageUrl))
                {
                    var image = IconCache.TryGetFromCache(_curPost.ImageUrl);
                    try
                    {
                        UserPicture.Image = image != null ? image.Clone() : null;
                    }
                    catch (Exception)
                    {
                        UserPicture.ShowErrorImage();
                    }
                }

                DateTimeLabel.Text = _curPost.CreatedAt.ToString();

                if (DumpPostClassToolStripMenuItem.Checked)
                {
                    StringBuilder sb = new StringBuilder(512);

                    sb.Append("-----Start PostClass Dump<br>");
                    sb.AppendFormat("TextFromApi           : {0}<br>", _curPost.TextFromApi);
                    sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.TextFromApi);
                    sb.AppendFormat("StatusId             : {0}<br>", _curPost.StatusId.ToString());
                    //sb.AppendFormat("ImageIndex     : {0}<br>", _curPost.ImageIndex.ToString());
                    sb.AppendFormat("ImageUrl       : {0}<br>", _curPost.ImageUrl);
                    sb.AppendFormat("InReplyToStatusId    : {0}<br>", _curPost.InReplyToStatusId.ToString());
                    sb.AppendFormat("InReplyToUser  : {0}<br>", _curPost.InReplyToUser);
                    sb.AppendFormat("IsDM           : {0}<br>", _curPost.IsDm.ToString());
                    sb.AppendFormat("IsFav          : {0}<br>", _curPost.IsFav.ToString());
                    sb.AppendFormat("IsMark         : {0}<br>", _curPost.IsMark.ToString());
                    sb.AppendFormat("IsMe           : {0}<br>", _curPost.IsMe.ToString());
                    sb.AppendFormat("IsOwl          : {0}<br>", _curPost.IsOwl.ToString());
                    sb.AppendFormat("IsProtect      : {0}<br>", _curPost.IsProtect.ToString());
                    sb.AppendFormat("IsRead         : {0}<br>", _curPost.IsRead.ToString());
                    sb.AppendFormat("IsReply        : {0}<br>", _curPost.IsReply.ToString());

                    foreach (string nm in _curPost.ReplyToList)
                    {
                        sb.AppendFormat("ReplyToList    : {0}<br>", nm);
                    }

                    sb.AppendFormat("ScreenName           : {0}<br>", _curPost.ScreenName);
                    sb.AppendFormat("NickName       : {0}<br>", _curPost.Nickname);
                    sb.AppendFormat("Text   : {0}<br>", _curPost.Text);
                    sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.Text);
                    sb.AppendFormat("CreatedAt          : {0}<br>", _curPost.CreatedAt.ToString());
                    sb.AppendFormat("Source         : {0}<br>", _curPost.Source);
                    sb.AppendFormat("UserId            : {0}<br>", _curPost.UserId);
                    sb.AppendFormat("FilterHit      : {0}<br>", _curPost.FilterHit);
                    sb.AppendFormat("RetweetedBy    : {0}<br>", _curPost.RetweetedBy);
                    sb.AppendFormat("RetweetedId    : {0}<br>", _curPost.RetweetedId);
                    sb.AppendFormat("SearchTabName  : {0}<br>", _curPost.RelTabName);
                    sb.Append("-----End PostClass Dump<br>");

                    PostBrowser.DocumentText = detailHtmlFormatHeader + sb.ToString() + detailHtmlFormatFooter;
                }
                else
                {
                    // 同じIDのツイートであれば WebBrowser とサムネイルの更新を行わない
                    // (同一ツイートの RT は文面が同じであるため同様に更新しない)
                    if (_curPost.StatusId != oldDisplayPost.StatusId)
                    {
                        this.PostBrowser.DocumentText =
                            this.createDetailHtml(_curPost.IsDeleted ? "(DELETED)" : _curPost.Text);

                        this.PostBrowser.Document.Window.ScrollTo(0, 0);

                        this.SplitContainer3.Panel2Collapsed = true;

                        if (this._cfgCommon.PreviewEnable)
                        {
                            if (this.thumbnailTokenSource != null)
                            {
                                var oldTokenSource = this.thumbnailTokenSource;

                                var cancelTask = Task.Run(() => oldTokenSource.Cancel());

                                Task.WhenAll(this.thumbnailTask, cancelTask)
                                    .ContinueWith(_ => oldTokenSource.Dispose(), TaskScheduler.Default);
                            }

                            this.thumbnailTokenSource = new CancellationTokenSource();

                            var token = this.thumbnailTokenSource.Token;
                            this.thumbnailTask = this.tweetThumbnail1.ShowThumbnailAsync(_curPost, token);
                        }
                    }
                }
            }
        }
Пример #4
0
        private async void MyList_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
        {
            ListViewItem item = null;
            PostClass cacheItemPost = null;

            if (_curList.Equals(sender))
                this.TryGetListViewItemCache(e.ItemIndex, out item, out cacheItemPost);

            if (item == null)
            {
                //A cache miss, so create a new ListViewItem and pass it back.
                TabPage tb = (TabPage)((DetailsListView)sender).Parent;
                try
                {
                    item = this.CreateItem(tb, _statuses[tb.Text, e.ItemIndex], e.ItemIndex);
                }
                catch (Exception)
                {
                    //不正な要求に対する間に合わせの応答
                    string[] sitem = {"", "", "", "", "", "", "", ""};
                    item = new ImageListViewItem(sitem);
                }
            }

            // e.Item に値をセットする前に await しないこと
            e.Item = item;

            await ((ImageListViewItem)item).GetImageAsync();
        }
Пример #5
0
        private async Task DispSelectedPost(bool forceupdate)
        {
            if (_curList.SelectedIndices.Count == 0 || _curPost == null)
                return;

            var oldDisplayPost = this.displayPost;
            this.displayPost = this._curPost;

            if (!forceupdate && this._curPost.Equals(oldDisplayPost))
                return;

            if (displayItem != null)
            {
                displayItem.ImageDownloaded -= this.DisplayItemImage_Downloaded;
                displayItem = null;
            }
            displayItem = (ImageListViewItem)_curList.Items[_curList.SelectedIndices[0]];
            displayItem.ImageDownloaded += this.DisplayItemImage_Downloaded;

            using (ControlTransaction.Update(this.TableLayoutPanel1))
            {
                SourceLinkLabel.Text = this._curPost.Source;
                SourceLinkLabel.Tag = this._curPost.SourceUri;
                SourceLinkLabel.TabStop = false; // Text を更新すると勝手に true にされる

                string nameText;
                if (_curPost.IsDm)
                {
                    if (_curPost.IsOwl)
                        nameText = "DM FROM <- ";
                    else
                        nameText = "DM TO -> ";
                }
                else
                {
                    nameText = "";
                }
                nameText += _curPost.ScreenName + "/" + _curPost.Nickname;
                if (_curPost.RetweetedId != null)
                    nameText += " (RT:" + _curPost.RetweetedBy + ")";

                NameLabel.Text = nameText;
                NameLabel.Tag = _curPost.ScreenName;

                var nameForeColor = SystemColors.ControlText;
                if (_curPost.IsFav)
                    nameForeColor = this._clFav;
                else if (_curPost.RetweetedId != null)
                    nameForeColor = this._clRetweet;
                else if (_curPost.IsOwl && (this._cfgCommon.OneWayLove || _curPost.IsDm))
                    nameForeColor = this._clOWL;
                NameLabel.ForeColor = nameForeColor;

                this.ClearUserPicture();

                if (!string.IsNullOrEmpty(_curPost.ImageUrl))
                {
                    var image = IconCache.TryGetFromCache(_curPost.ImageUrl);
                    try
                    {
                        UserPicture.Image = image != null ? image.Clone() : null;
                    }
                    catch (Exception)
                    {
                        UserPicture.ShowErrorImage();
                    }
                }

                DateTimeLabel.Text = _curPost.CreatedAt.ToString();
            }

            if (DumpPostClassToolStripMenuItem.Checked)
            {
                StringBuilder sb = new StringBuilder(512);

                sb.Append("-----Start PostClass Dump<br>");
                sb.AppendFormat("TextFromApi           : {0}<br>", _curPost.TextFromApi);
                sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.TextFromApi);
                sb.AppendFormat("StatusId             : {0}<br>", _curPost.StatusId.ToString());
                //sb.AppendFormat("ImageIndex     : {0}<br>", _curPost.ImageIndex.ToString());
                sb.AppendFormat("ImageUrl       : {0}<br>", _curPost.ImageUrl);
                sb.AppendFormat("InReplyToStatusId    : {0}<br>", _curPost.InReplyToStatusId.ToString());
                sb.AppendFormat("InReplyToUser  : {0}<br>", _curPost.InReplyToUser);
                sb.AppendFormat("IsDM           : {0}<br>", _curPost.IsDm.ToString());
                sb.AppendFormat("IsFav          : {0}<br>", _curPost.IsFav.ToString());
                sb.AppendFormat("IsMark         : {0}<br>", _curPost.IsMark.ToString());
                sb.AppendFormat("IsMe           : {0}<br>", _curPost.IsMe.ToString());
                sb.AppendFormat("IsOwl          : {0}<br>", _curPost.IsOwl.ToString());
                sb.AppendFormat("IsProtect      : {0}<br>", _curPost.IsProtect.ToString());
                sb.AppendFormat("IsRead         : {0}<br>", _curPost.IsRead.ToString());
                sb.AppendFormat("IsReply        : {0}<br>", _curPost.IsReply.ToString());

                foreach (string nm in _curPost.ReplyToList)
                {
                    sb.AppendFormat("ReplyToList    : {0}<br>", nm);
                }

                sb.AppendFormat("ScreenName           : {0}<br>", _curPost.ScreenName);
                sb.AppendFormat("NickName       : {0}<br>", _curPost.Nickname);
                sb.AppendFormat("Text   : {0}<br>", _curPost.Text);
                sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.Text);
                sb.AppendFormat("CreatedAt          : {0}<br>", _curPost.CreatedAt.ToString());
                sb.AppendFormat("Source         : {0}<br>", _curPost.Source);
                sb.AppendFormat("UserId            : {0}<br>", _curPost.UserId);
                sb.AppendFormat("FilterHit      : {0}<br>", _curPost.FilterHit);
                sb.AppendFormat("RetweetedBy    : {0}<br>", _curPost.RetweetedBy);
                sb.AppendFormat("RetweetedId    : {0}<br>", _curPost.RetweetedId);
                sb.AppendFormat("SearchTabName  : {0}<br>", _curPost.RelTabName);

                sb.AppendFormat("Media.Count    : {0}<br>", _curPost.Media.Count);
                if (_curPost.Media.Count > 0)
                {
                    for (int i = 0; i < _curPost.Media.Count; i++)
                    {
                        var info = _curPost.Media[i];
                        sb.AppendFormat("Media[{0}].Url         : {1}<br>", i, info.Url);
                        sb.AppendFormat("Media[{0}].VideoUrl    : {1}<br>", i, info.VideoUrl ?? "---");
                    }
                }
                sb.Append("-----End PostClass Dump<br>");

                PostBrowser.DocumentText = detailHtmlFormatHeader + sb.ToString() + detailHtmlFormatFooter;
                return;
            }

            var loadTasks = new List<Task>();

            // 同じIDのツイートであれば WebBrowser とサムネイルの更新を行わない
            // (同一ツイートの RT は文面が同じであるため同様に更新しない)
            if (_curPost.StatusId != oldDisplayPost.StatusId)
            {
                using (ControlTransaction.Update(this.PostBrowser))
                {
                    this.PostBrowser.DocumentText =
                        this.createDetailHtml(_curPost.IsDeleted ? "(DELETED)" : _curPost.Text);

                    this.PostBrowser.Document.Window.ScrollTo(0, 0);
                }

                this.SplitContainer3.Panel2Collapsed = true;

                if (this._cfgCommon.PreviewEnable)
                {
                    var oldTokenSource = Interlocked.Exchange(ref this.thumbnailTokenSource, new CancellationTokenSource());
                    if (oldTokenSource != null)
                        oldTokenSource.Cancel();

                    var token = this.thumbnailTokenSource.Token;
                    loadTasks.Add(this.tweetThumbnail1.ShowThumbnailAsync(_curPost, token));
                }

                loadTasks.Add(this.AppendQuoteTweetAsync(this._curPost));
            }

            try
            {
                await Task.WhenAll(loadTasks);
            }
            catch (OperationCanceledException) { }
        }
Пример #6
0
        private void DispSelectedPost(bool forceupdate)
        {
            if (_curList.SelectedIndices.Count == 0 || _curPost == null)
                return;

            if (!forceupdate && _curPost.Equals(displaypost))
                return;

            displaypost = _curPost;
            if (displayItem != null)
            {
                displayItem.ImageDownloaded -= this.DisplayItemImage_Downloaded;
                displayItem = null;
            }
            displayItem = (ImageListViewItem)_curList.Items[_curList.SelectedIndices[0]];
            displayItem.ImageDownloaded += this.DisplayItemImage_Downloaded;

            string dTxt = createDetailHtml(_curPost.IsDeleted ? "(DELETED)" : _curPost.Text);
            if (_curPost.IsDm)
            {
                SourceLinkLabel.Tag = null;
                SourceLinkLabel.Text = "";
            }
            else
            {
                Match mc = Regex.Match(_curPost.SourceHtml, "<a href=\"(?<sourceurl>.+?)\"");
                if (mc.Success)
                {
                    string src = mc.Groups["sourceurl"].Value;
                    SourceLinkLabel.Tag = mc.Groups["sourceurl"].Value;
                    mc = Regex.Match(src, "^https?://");
                    if (!mc.Success)
                    {
                        src = src.Insert(0, "https://twitter.com");
                    }
                    SourceLinkLabel.Tag = src;
                }
                else
                {
                    SourceLinkLabel.Tag = null;
                }
                if (string.IsNullOrEmpty(_curPost.Source))
                {
                    SourceLinkLabel.Text = "";
                    //SourceLinkLabel.Visible = false;
                }
                else
                {
                    SourceLinkLabel.Text = _curPost.Source;
                    //SourceLinkLabel.Visible = true;
                }
            }
            SourceLinkLabel.TabStop = false;

            if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage && !_curPost.IsOwl)
            {
                NameLabel.Text = "DM TO -> ";
            }
            else if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage)
            {
                NameLabel.Text = "DM FROM <- ";
            }
            else
            {
                NameLabel.Text = "";
            }
            NameLabel.Text += _curPost.ScreenName + "/" + _curPost.Nickname;
            NameLabel.Tag = _curPost.ScreenName;
            if (!string.IsNullOrEmpty(_curPost.RetweetedBy))
            {
                NameLabel.Text += " (RT:" + _curPost.RetweetedBy + ")";
            }

            this.ClearUserPicture();

            if (!string.IsNullOrEmpty(_curPost.ImageUrl))
            {
                var image = IconCache.TryGetFromCache(_curPost.ImageUrl);
                try
                {
                    UserPicture.Image = image != null ? image.Clone() : null;
                }
                catch (Exception)
                {
                    UserPicture.ShowErrorImage();
                }
            }

            NameLabel.ForeColor = System.Drawing.SystemColors.ControlText;
            DateTimeLabel.Text = _curPost.CreatedAt.ToString();
            if (_curPost.IsOwl && (SettingDialog.OneWayLove || _statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage)) NameLabel.ForeColor = _clOWL;
            if (_curPost.RetweetedId != null) NameLabel.ForeColor = _clRetweet;
            if (_curPost.IsFav) NameLabel.ForeColor = _clFav;

            if (DumpPostClassToolStripMenuItem.Checked)
            {
                StringBuilder sb = new StringBuilder(512);

                sb.Append("-----Start PostClass Dump<br>");
                sb.AppendFormat("TextFromApi           : {0}<br>", _curPost.TextFromApi);
                sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.TextFromApi);
                sb.AppendFormat("StatusId             : {0}<br>", _curPost.StatusId.ToString());
                //sb.AppendFormat("ImageIndex     : {0}<br>", _curPost.ImageIndex.ToString());
                sb.AppendFormat("ImageUrl       : {0}<br>", _curPost.ImageUrl);
                sb.AppendFormat("InReplyToStatusId    : {0}<br>", _curPost.InReplyToStatusId.ToString());
                sb.AppendFormat("InReplyToUser  : {0}<br>", _curPost.InReplyToUser);
                sb.AppendFormat("IsDM           : {0}<br>", _curPost.IsDm.ToString());
                sb.AppendFormat("IsFav          : {0}<br>", _curPost.IsFav.ToString());
                sb.AppendFormat("IsMark         : {0}<br>", _curPost.IsMark.ToString());
                sb.AppendFormat("IsMe           : {0}<br>", _curPost.IsMe.ToString());
                sb.AppendFormat("IsOwl          : {0}<br>", _curPost.IsOwl.ToString());
                sb.AppendFormat("IsProtect      : {0}<br>", _curPost.IsProtect.ToString());
                sb.AppendFormat("IsRead         : {0}<br>", _curPost.IsRead.ToString());
                sb.AppendFormat("IsReply        : {0}<br>", _curPost.IsReply.ToString());
            
                foreach (string nm in _curPost.ReplyToList)
                {
                    sb.AppendFormat("ReplyToList    : {0}<br>", nm);
                }

                sb.AppendFormat("ScreenName           : {0}<br>", _curPost.ScreenName);
                sb.AppendFormat("NickName       : {0}<br>", _curPost.Nickname);
                sb.AppendFormat("Text   : {0}<br>", _curPost.Text);
                sb.AppendFormat("(PlainText)    : <xmp>{0}</xmp><br>", _curPost.Text);
                sb.AppendFormat("CreatedAt          : {0}<br>", _curPost.CreatedAt.ToString());
                sb.AppendFormat("Source         : {0}<br>", _curPost.Source);
                sb.AppendFormat("UserId            : {0}<br>", _curPost.UserId);
                sb.AppendFormat("FilterHit      : {0}<br>", _curPost.FilterHit);
                sb.AppendFormat("RetweetedBy    : {0}<br>", _curPost.RetweetedBy);
                sb.AppendFormat("RetweetedId    : {0}<br>", _curPost.RetweetedId);
                sb.AppendFormat("SearchTabName  : {0}<br>", _curPost.RelTabName);
                sb.Append("-----End PostClass Dump<br>");

                PostBrowser.Visible = false;
                PostBrowser.DocumentText = detailHtmlFormatHeader + sb.ToString() + detailHtmlFormatFooter;
                PostBrowser.Visible = true;
            }
            else
            {
                try
                {
                    if (PostBrowser.DocumentText != dTxt)
                    {
                        PostBrowser.Visible = false;
                        PostBrowser.DocumentText = dTxt;

                        this.SplitContainer3.Panel2Collapsed = true;

                        if (this.IsPreviewEnable)
                        {
                            if (this.thumbnailTokenSource != null)
                            {
                                var oldTokenSource = this.thumbnailTokenSource;
                                oldTokenSource.Cancel();
                                this.thumbnailTask.ContinueWith(_ => oldTokenSource.Dispose());
                            }

                            this.thumbnailTokenSource = new CancellationTokenSource();

                            var token = this.thumbnailTokenSource.Token;
                            this.thumbnailTask = this.tweetThumbnail1.ShowThumbnailAsync(_curPost, token);
                        }
                    }
                }
                catch (System.Runtime.InteropServices.COMException)
                {
                    //原因不明
                }
                catch (UriFormatException)
                {
                    PostBrowser.DocumentText = dTxt;
                }
                finally
                {
                    PostBrowser.Visible = true;
                }
            }
        }