OSDN Git Service

SGenタスクでシリアル化アセンブリを生成する対象の型を Setting* クラスに限定
[opentween/open-tween.git] / OpenTween / UserInfoDialog.cs
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.
9 // 
10 // This file is part of OpenTween.
11 // 
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)
15 // any later version.
16 // 
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
20 // for more details. 
21 // 
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.
26
27 using System;
28 using System.Collections.Generic;
29 using System.ComponentModel;
30 using System.Data;
31 using System.Drawing;
32 using System.Linq;
33 using System.Text;
34 using System.Threading.Tasks;
35 using System.Windows.Forms;
36 using System.Text.RegularExpressions;
37 using System.Web;
38 using System.IO;
39 using System.Net;
40
41 namespace OpenTween
42 {
43     public partial class UserInfoDialog : OTBaseForm
44     {
45         private TwitterDataModel.User _displayUser;
46         public TwitterDataModel.User DisplayUser
47         {
48             get { return this._displayUser; }
49             set
50             {
51                 if (this._displayUser != value)
52                 {
53                     this._displayUser = value;
54                     this.OnDisplayUserChanged();
55                 }
56             }
57         }
58
59         private new TweenMain Owner
60         {
61             get { return (TweenMain)base.Owner; }
62         }
63
64         private Twitter Twitter
65         {
66             get { return this.Owner.TwitterInstance; }
67         }
68
69         public UserInfoDialog()
70         {
71             InitializeComponent();
72
73             // LabelScreenName のフォントを OTBaseForm.GlobalFont に変更
74             this.LabelScreenName.Font = this.ReplaceToGlobalFont(this.LabelScreenName.Font);
75         }
76
77         protected virtual async void OnDisplayUserChanged()
78         {
79             if (this._displayUser == null)
80                 return;
81
82             var user = this._displayUser;
83
84             this.LabelId.Text = user.IdStr;
85             this.LabelScreenName.Text = user.ScreenName;
86             this.LabelName.Text = WebUtility.HtmlDecode(user.Name);
87             this.LabelLocation.Text = user.Location ?? "";
88             this.LabelCreatedAt.Text = MyCommon.DateTimeParse(user.CreatedAt).ToString();
89
90             if (user.Protected)
91                 this.LabelIsProtected.Text = Properties.Resources.Yes;
92             else
93                 this.LabelIsProtected.Text = Properties.Resources.No;
94
95             if (user.Verified)
96                 this.LabelIsVerified.Text = Properties.Resources.Yes;
97             else
98                 this.LabelIsVerified.Text = Properties.Resources.No;
99
100             var followingUrl = "https://twitter.com/" + user.ScreenName + "/following";
101             this.LinkLabelFollowing.Text = user.FriendsCount.ToString();
102             this.LinkLabelFollowing.Tag = followingUrl;
103             this.ToolTip1.SetToolTip(this.LinkLabelFollowing, followingUrl);
104
105             var followersUrl = "https://twitter.com/" + user.ScreenName + "/followers";
106             this.LinkLabelFollowers.Text = user.FollowersCount.ToString();
107             this.LinkLabelFollowers.Tag = followersUrl;
108             this.ToolTip1.SetToolTip(this.LinkLabelFollowers, followersUrl);
109
110             var favoritesUrl = "https://twitter.com/" + user.ScreenName + "/favorites";
111             this.LinkLabelFav.Text = user.FavouritesCount.ToString();
112             this.LinkLabelFav.Tag = favoritesUrl;
113             this.ToolTip1.SetToolTip(this.LinkLabelFav, favoritesUrl);
114
115             var profileUrl = "https://twitter.com/" + user.ScreenName;
116             this.LinkLabelTweet.Text = user.StatusesCount.ToString();
117             this.LinkLabelTweet.Tag = profileUrl;
118             this.ToolTip1.SetToolTip(this.LinkLabelTweet, profileUrl);
119
120             if (this.Twitter.UserId == user.Id)
121             {
122                 this.ButtonEdit.Enabled = true;
123                 this.ChangeIconToolStripMenuItem.Enabled = true;
124                 this.ButtonBlock.Enabled = false;
125                 this.ButtonReportSpam.Enabled = false;
126                 this.ButtonBlockDestroy.Enabled = false;
127             }
128             else
129             {
130                 this.ButtonEdit.Enabled = false;
131                 this.ChangeIconToolStripMenuItem.Enabled = false;
132                 this.ButtonBlock.Enabled = true;
133                 this.ButtonReportSpam.Enabled = true;
134                 this.ButtonBlockDestroy.Enabled = true;
135             }
136
137             await Task.WhenAll(new[]
138             {
139                 this.SetDescriptionAsync(user.Description),
140                 this.SetRecentStatusAsync(user.Status),
141                 this.SetLinkLabelWebAsync(user.Url),
142                 this.SetUserImageAsync(user.ProfileImageUrlHttps),
143                 this.LoadFriendshipAsync(user.ScreenName),
144             });
145         }
146
147         private async Task SetDescriptionAsync(string descriptionText)
148         {
149             if (descriptionText != null)
150             {
151                 var atlist = new List<string>();
152
153                 var html = WebUtility.HtmlEncode(descriptionText);
154                 html = await this.Twitter.CreateHtmlAnchorAsync(html, atlist, null);
155                 html = this.Owner.createDetailHtml(html);
156
157                 this.DescriptionBrowser.DocumentText = html;
158             }
159             else
160             {
161                 this.DescriptionBrowser.DocumentText = "";
162             }
163         }
164
165         private async Task SetUserImageAsync(string imageUri)
166         {
167             var oldImage = this.UserPicture.Image;
168             if (oldImage != null)
169             {
170                 this.UserPicture.Image = null;
171                 oldImage.Dispose();
172             }
173
174             using (var http = MyCommon.CreateHttpClient())
175             {
176                 var imageStream = await http.GetStreamAsync(imageUri.Replace("_normal", "_bigger"));
177                 this.UserPicture.Image = await MemoryImage.CopyFromStreamAsync(imageStream);
178             }
179         }
180
181         private async Task SetLinkLabelWebAsync(string uri)
182         {
183             if (uri != null)
184             {
185                 var expandedUrl = await ShortUrl.Instance.ExpandUrlStrAsync(uri);
186
187                 this.LinkLabelWeb.Text = uri;
188                 this.LinkLabelWeb.Tag = expandedUrl;
189                 this.ToolTip1.SetToolTip(this.LinkLabelWeb, expandedUrl);
190             }
191             else
192             {
193                 this.LinkLabelWeb.Text = "";
194                 this.LinkLabelWeb.Tag = null;
195                 this.ToolTip1.SetToolTip(this.LinkLabelWeb, null);
196             }
197         }
198
199         private async Task SetRecentStatusAsync(TwitterDataModel.Status status)
200         {
201             var atlist = new List<string>();
202
203             if (status != null)
204             {
205                 var html = await this.Twitter.CreateHtmlAnchorAsync(status.Text, atlist, status.Entities, null);
206                 html = this.Owner.createDetailHtml(html +
207                     " Posted at " + MyCommon.DateTimeParse(status.CreatedAt) +
208                     " via " + status.Source);
209
210                 this.RecentPostBrowser.DocumentText = html;
211             }
212             else
213             {
214                 this.RecentPostBrowser.DocumentText = Properties.Resources.ShowUserInfo2;
215             }
216         }
217
218         private async Task LoadFriendshipAsync(string screenName)
219         {
220             this.LabelIsFollowing.Text = "";
221             this.LabelIsFollowed.Text = "";
222             this.ButtonFollow.Enabled = false;
223             this.ButtonUnFollow.Enabled = false;
224
225             if (this.Twitter.Username == screenName)
226                 return;
227
228             var friendship = await Task.Run(() =>
229             {
230                 var IsFollowing = false;
231                 var IsFollowedBy = false;
232
233                 var ret = this.Twitter.GetFriendshipInfo(screenName, ref IsFollowing, ref IsFollowedBy);
234                 if (!string.IsNullOrEmpty(ret))
235                     return null;
236
237                 return new { IsFollowing, IsFollowedBy };
238             });
239
240             if (friendship == null)
241             {
242                 LabelIsFollowed.Text = Properties.Resources.GetFriendshipInfo6;
243                 LabelIsFollowing.Text = Properties.Resources.GetFriendshipInfo6;
244                 return;
245             }
246
247             this.LabelIsFollowing.Text = friendship.IsFollowing
248                 ? Properties.Resources.GetFriendshipInfo1
249                 : Properties.Resources.GetFriendshipInfo2;
250
251             this.LabelIsFollowed.Text = friendship.IsFollowedBy
252                 ? Properties.Resources.GetFriendshipInfo3
253                 : Properties.Resources.GetFriendshipInfo4;
254
255             this.ButtonFollow.Enabled = !friendship.IsFollowing;
256             this.ButtonUnFollow.Enabled = friendship.IsFollowing;
257         }
258
259         private void ShowUserInfo_Load(object sender, EventArgs e)
260         {
261             this.TextBoxName.Location = this.LabelName.Location;
262             this.TextBoxName.Height = this.LabelName.Height;
263             this.TextBoxName.Width = this.LabelName.Width;
264             this.TextBoxName.BackColor = this.Owner.InputBackColor;
265             this.TextBoxName.MaxLength = 20;
266
267             this.TextBoxLocation.Location = this.LabelLocation.Location;
268             this.TextBoxLocation.Height = this.LabelLocation.Height;
269             this.TextBoxLocation.Width = this.LabelLocation.Width;
270             this.TextBoxLocation.BackColor = this.Owner.InputBackColor;
271             this.TextBoxLocation.MaxLength = 30;
272
273             this.TextBoxWeb.Location = this.LinkLabelWeb.Location;
274             this.TextBoxWeb.Height = this.LinkLabelWeb.Height;
275             this.TextBoxWeb.Width = this.LinkLabelWeb.Width;
276             this.TextBoxWeb.BackColor = this.Owner.InputBackColor;
277             this.TextBoxWeb.MaxLength = 100;
278
279             this.TextBoxDescription.Location = this.DescriptionBrowser.Location;
280             this.TextBoxDescription.Height = this.DescriptionBrowser.Height;
281             this.TextBoxDescription.Width = this.DescriptionBrowser.Width;
282             this.TextBoxDescription.BackColor = this.Owner.InputBackColor;
283             this.TextBoxDescription.MaxLength = 160;
284             this.TextBoxDescription.Multiline = true;
285             this.TextBoxDescription.ScrollBars = ScrollBars.Vertical;
286         }
287
288         private async void LinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
289         {
290             var linkLabel = (LinkLabel)sender;
291
292             var linkUrl = (string)linkLabel.Tag;
293             if (linkUrl == null)
294                 return;
295
296             await this.Owner.OpenUriAsync(linkUrl);
297         }
298
299         private void ButtonFollow_Click(object sender, EventArgs e)
300         {
301             string ret = this.Twitter.PostFollowCommand(this._displayUser.ScreenName);
302             if (!string.IsNullOrEmpty(ret))
303             {
304                 MessageBox.Show(Properties.Resources.FRMessage2 + ret);
305             }
306             else
307             {
308                 MessageBox.Show(Properties.Resources.FRMessage3);
309                 LabelIsFollowing.Text = Properties.Resources.GetFriendshipInfo1;
310                 ButtonFollow.Enabled = false;
311                 ButtonUnFollow.Enabled = true;
312             }
313         }
314
315         private void ButtonUnFollow_Click(object sender, EventArgs e)
316         {
317             if (MessageBox.Show(this._displayUser.ScreenName + Properties.Resources.ButtonUnFollow_ClickText1,
318                                Properties.Resources.ButtonUnFollow_ClickText2,
319                                MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
320             {
321                 string ret = this.Twitter.PostRemoveCommand(this._displayUser.ScreenName);
322                 if (!string.IsNullOrEmpty(ret))
323                 {
324                     MessageBox.Show(Properties.Resources.FRMessage2 + ret);
325                 }
326                 else
327                 {
328                     MessageBox.Show(Properties.Resources.FRMessage3);
329                     LabelIsFollowing.Text = Properties.Resources.GetFriendshipInfo2;
330                     ButtonFollow.Enabled = true;
331                     ButtonUnFollow.Enabled = false;
332                 }
333             }
334         }
335
336         private void ShowUserInfo_Activated(object sender, EventArgs e)
337         {
338             //画面が他画面の裏に隠れると、アイコン画像が再描画されない問題の対応
339             if (UserPicture.Image != null)
340                 UserPicture.Invalidate(false);
341         }
342
343         private void ShowUserInfo_Shown(object sender, EventArgs e)
344         {
345             ButtonClose.Focus();
346         }
347
348         private void WebBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
349         {
350             if (e.Url.AbsoluteUri != "about:blank")
351             {
352                 e.Cancel = true;
353
354                 if (e.Url.AbsoluteUri.StartsWith("http://twitter.com/search?q=%23") ||
355                     e.Url.AbsoluteUri.StartsWith("https://twitter.com/search?q=%23"))
356                 {
357                     //ハッシュタグの場合は、タブで開く
358                     string urlStr = Uri.UnescapeDataString(e.Url.AbsoluteUri);
359                     string hash = urlStr.Substring(urlStr.IndexOf("#"));
360                     this.Owner.HashSupl.AddItem(hash);
361                     this.Owner.HashMgr.AddHashToHistory(hash.Trim(), false);
362                     this.Owner.AddNewTabForSearch(hash);
363                     return;
364                 }
365                 else
366                 {
367                     Match m = Regex.Match(e.Url.AbsoluteUri, @"^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)$");
368                     if (AppendSettingDialog.Instance.OpenUserTimeline && m.Success && this.Owner.IsTwitterId(m.Result("${ScreenName}")))
369                     {
370                         this.Owner.AddNewTabForUserTimeline(m.Result("${ScreenName}"));
371                     }
372                     else
373                     {
374                         this.Owner.OpenUriAsync(e.Url.OriginalString);
375                     }
376                 }
377             }
378         }
379
380         private void SelectAllToolStripMenuItem_Click(object sender, EventArgs e)
381         {
382             var browser = (WebBrowser)this.ContextMenuRecentPostBrowser.SourceControl;
383             browser.Document.ExecCommand("SelectAll", false, null);
384         }
385
386         private void SelectionCopyToolStripMenuItem_Click(object sender, EventArgs e)
387         {
388             var browser = (WebBrowser)this.ContextMenuRecentPostBrowser.SourceControl;
389             var selectedText = this.Owner.WebBrowser_GetSelectionText(ref browser);
390             if (selectedText != null)
391             {
392                 try
393                 {
394                     Clipboard.SetDataObject(selectedText, false, 5, 100);
395                 }
396                 catch (Exception ex)
397                 {
398                     MessageBox.Show(ex.Message);
399                 }
400             }
401         }
402
403         private void ContextMenuRecentPostBrowser_Opening(object sender, CancelEventArgs e)
404         {
405             var browser = (WebBrowser)this.ContextMenuRecentPostBrowser.SourceControl;
406             var selectedText = this.Owner.WebBrowser_GetSelectionText(ref browser);
407
408             this.SelectionCopyToolStripMenuItem.Enabled = selectedText != null;
409         }
410
411         private void LinkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
412         {
413             this.Owner.OpenUriAsync("https://support.twitter.com/groups/31-twitter-basics/topics/111-features/articles/268350-x8a8d-x8a3c-x6e08-x307f-x30a2-x30ab-x30a6-x30f3-x30c8-x306b-x3064-x3044-x3066");
414         }
415
416         private void LinkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
417         {
418             this.Owner.OpenUriAsync("https://support.twitter.com/groups/31-twitter-basics/topics/107-my-profile-account-settings/articles/243055-x516c-x958b-x3001-x975e-x516c-x958b-x30a2-x30ab-x30a6-x30f3-x30c8-x306b-x3064-x3044-x3066");
419         }
420
421         private void ButtonSearchPosts_Click(object sender, EventArgs e)
422         {
423             this.Owner.AddNewTabForUserTimeline(this._displayUser.ScreenName);
424         }
425
426         private async void UserPicture_Click(object sender, EventArgs e)
427         {
428             var imageUrl = this._displayUser.ProfileImageUrlHttps;
429             imageUrl = imageUrl.Remove(imageUrl.LastIndexOf("_normal"), 7);
430
431             await this.Owner.OpenUriAsync(imageUrl);
432         }
433
434         private bool IsEditing = false;
435         private string ButtonEditText = "";
436
437         private async void ButtonEdit_Click(object sender, EventArgs e)
438         {
439             // 自分以外のプロフィールは変更できない
440             if (this.Twitter.UserId != this._displayUser.Id)
441                 return;
442
443             this.ButtonEdit.Enabled = false;
444
445             if (!IsEditing)
446             {
447                 ButtonEditText = ButtonEdit.Text;
448                 ButtonEdit.Text = Properties.Resources.UserInfoButtonEdit_ClickText1;
449
450                 TextBoxName.Text = LabelName.Text;
451                 TextBoxName.Enabled = true;
452                 TextBoxName.Visible = true;
453                 LabelName.Visible = false;
454
455                 TextBoxLocation.Text = LabelLocation.Text;
456                 TextBoxLocation.Enabled = true;
457                 TextBoxLocation.Visible = true;
458                 LabelLocation.Visible = false;
459
460                 TextBoxWeb.Text = this._displayUser.Url;
461                 TextBoxWeb.Enabled = true;
462                 TextBoxWeb.Visible = true;
463                 LinkLabelWeb.Visible = false;
464
465                 TextBoxDescription.Text = this._displayUser.Description;
466                 TextBoxDescription.Enabled = true;
467                 TextBoxDescription.Visible = true;
468                 DescriptionBrowser.Visible = false;
469
470                 TextBoxName.Focus();
471                 TextBoxName.Select(TextBoxName.Text.Length, 0);
472
473                 IsEditing = true;
474             }
475             else
476             {
477                 if (TextBoxName.Modified ||
478                     TextBoxLocation.Modified ||
479                     TextBoxWeb.Modified ||
480                     TextBoxDescription.Modified)
481                 {
482                     try
483                     {
484                         var user = await Task.Run(() =>
485                             this.Twitter.PostUpdateProfile(
486                                 this.TextBoxName.Text,
487                                 this.TextBoxWeb.Text,
488                                 this.TextBoxLocation.Text,
489                                 this.TextBoxDescription.Text));
490
491                         this.DisplayUser = user;
492                     }
493                     catch (WebApiException ex)
494                     {
495                         MessageBox.Show(ex.Message);
496                         return;
497                     }
498                 }
499
500                 TextBoxName.Enabled = false;
501                 TextBoxName.Visible = false;
502                 LabelName.Visible = true;
503
504                 TextBoxLocation.Enabled = false;
505                 TextBoxLocation.Visible = false;
506                 LabelLocation.Visible = true;
507
508                 TextBoxWeb.Enabled = false;
509                 TextBoxWeb.Visible = false;
510                 LinkLabelWeb.Visible = true;
511
512                 TextBoxDescription.Enabled = false;
513                 TextBoxDescription.Visible = false;
514                 DescriptionBrowser.Visible = true;
515
516                 ButtonEdit.Text = ButtonEditText;
517
518                 IsEditing = false;
519             }
520
521             this.ButtonEdit.Enabled = true;
522         }
523
524         private async Task DoChangeIcon(string filename)
525         {
526             var ret = await Task.Run(() =>
527                 this.Twitter.PostUpdateProfileImage(filename));
528
529             if (!string.IsNullOrEmpty(ret))
530             {
531                 // "Err:"が付いたエラーメッセージが返ってくる
532                 MessageBox.Show(ret + Environment.NewLine + Properties.Resources.ChangeIconToolStripMenuItem_ClickText4);
533             }
534             else
535             {
536                 MessageBox.Show(Properties.Resources.ChangeIconToolStripMenuItem_ClickText5);
537             }
538
539             try
540             {
541                 var user = await Task.Run(() =>
542                 {
543                     TwitterDataModel.User result = null;
544
545                     var err = this.Twitter.GetUserInfo(this._displayUser.ScreenName, ref result);
546                     if (!string.IsNullOrEmpty(err))
547                         throw new WebApiException(err);
548
549                     return result;
550                 });
551
552                 if (user != null)
553                     this.DisplayUser = user;
554             }
555             catch (WebApiException ex)
556             {
557                 MessageBox.Show(ex.Message);
558             }
559         }
560
561         private async void ChangeIconToolStripMenuItem_Click(object sender, EventArgs e)
562         {
563             OpenFileDialogIcon.Filter = Properties.Resources.ChangeIconToolStripMenuItem_ClickText1;
564             OpenFileDialogIcon.Title = Properties.Resources.ChangeIconToolStripMenuItem_ClickText2;
565             OpenFileDialogIcon.FileName = "";
566
567             DialogResult rslt = OpenFileDialogIcon.ShowDialog();
568
569             if (rslt != DialogResult.OK)
570             {
571                 return;
572             }
573
574             string fn = OpenFileDialogIcon.FileName;
575             if (this.IsValidIconFile(new FileInfo(fn)))
576             {
577                 await this.DoChangeIcon(fn);
578             }
579             else
580             {
581                 MessageBox.Show(Properties.Resources.ChangeIconToolStripMenuItem_ClickText6);
582             }
583         }
584
585         private void ButtonBlock_Click(object sender, EventArgs e)
586         {
587             if (MessageBox.Show(this._displayUser.ScreenName + Properties.Resources.ButtonBlock_ClickText1,
588                                 Properties.Resources.ButtonBlock_ClickText2,
589                                 MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
590             {
591                 string res = this.Twitter.PostCreateBlock(this._displayUser.ScreenName);
592                 if (!string.IsNullOrEmpty(res))
593                 {
594                     MessageBox.Show(res + Environment.NewLine + Properties.Resources.ButtonBlock_ClickText3);
595                 }
596                 else
597                 {
598                     MessageBox.Show(Properties.Resources.ButtonBlock_ClickText4);
599                 }
600             }
601         }
602
603         private void ButtonReportSpam_Click(object sender, EventArgs e)
604         {
605             if (MessageBox.Show(this._displayUser.ScreenName + Properties.Resources.ButtonReportSpam_ClickText1,
606                                 Properties.Resources.ButtonReportSpam_ClickText2,
607                                 MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
608             {
609                 string res = this.Twitter.PostReportSpam(this._displayUser.ScreenName);
610                 if (!string.IsNullOrEmpty(res))
611                 {
612                     MessageBox.Show(res + Environment.NewLine + Properties.Resources.ButtonReportSpam_ClickText3);
613                 }
614                 else
615                 {
616                     MessageBox.Show(Properties.Resources.ButtonReportSpam_ClickText4);
617                 }
618             }
619         }
620
621         private void ButtonBlockDestroy_Click(object sender, EventArgs e)
622         {
623             if (MessageBox.Show(this._displayUser.ScreenName + Properties.Resources.ButtonBlockDestroy_ClickText1,
624                                 Properties.Resources.ButtonBlockDestroy_ClickText2,
625                                 MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
626             {
627                 string res = this.Twitter.PostDestroyBlock(this._displayUser.ScreenName);
628                 if (!string.IsNullOrEmpty(res))
629                 {
630                     MessageBox.Show(res + Environment.NewLine + Properties.Resources.ButtonBlockDestroy_ClickText3);
631                 }
632                 else
633                 {
634                     MessageBox.Show(Properties.Resources.ButtonBlockDestroy_ClickText4);
635                 }
636             }
637         }
638
639         private bool IsValidExtension(string ext)
640         {
641             ext = ext.ToLower();
642
643             return ext.Equals(".jpg", StringComparison.Ordinal) ||
644                 ext.Equals(".jpeg", StringComparison.Ordinal) ||
645                 ext.Equals(".png", StringComparison.Ordinal) ||
646                 ext.Equals(".gif", StringComparison.Ordinal);
647         }
648
649         private bool IsValidIconFile(FileInfo info)
650         {
651             return this.IsValidExtension(info.Extension) &&
652                 info.Length < 700 * 1024 &&
653                 !MyCommon.IsAnimatedGif(info.FullName);
654         }
655
656         private void ShowUserInfo_DragOver(object sender, DragEventArgs e)
657         {
658             if (e.Data.GetDataPresent(DataFormats.FileDrop))
659             {
660                 var files = (string[])e.Data.GetData(DataFormats.FileDrop, false);
661                 if (files.Length != 1)
662                     return;
663
664                 var finfo = new FileInfo(files[0]);
665                 if (this.IsValidIconFile(finfo))
666                 {
667                     e.Effect = DragDropEffects.Copy;
668                 }
669             }
670         }
671
672         private async void ShowUserInfo_DragDrop(object sender, DragEventArgs e)
673         {
674             if (e.Data.GetDataPresent(DataFormats.FileDrop))
675             {
676                 string filename = ((string[])e.Data.GetData(DataFormats.FileDrop, false))[0];
677                 await this.DoChangeIcon(filename);
678             }
679         }
680
681         protected override void Dispose(bool disposing)
682         {
683             if (disposing)
684             {
685                 var oldImage = this.UserPicture.Image;
686                 if (oldImage != null)
687                 {
688                     this.UserPicture.Image = null;
689                     oldImage.Dispose();
690                 }
691
692                 if (this.components != null)
693                     this.components.Dispose();
694             }
695
696             base.Dispose(disposing);
697         }
698     }
699 }