OSDN Git Service

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