1 // OpenTween - Client of Twitter
2 // Copyright (c) 2007-2011 kiri_feather (@kiri_feather) <kiri.feather@gmail.com>
3 // (c) 2008-2011 Moz (@syo68k)
4 // (c) 2008-2011 takeshik (@takeshik) <http://www.takeshik.org/>
5 // (c) 2010-2011 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
6 // (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
7 // (c) 2011 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
8 // All rights reserved.
10 // This file is part of OpenTween.
12 // This program is free software; you can redistribute it and/or modify it
13 // under the terms of the GNU General Public License as published by the Free
14 // Software Foundation; either version 3 of the License, or (at your option)
17 // This program is distributed in the hope that it will be useful, but
18 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
24 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
25 // Boston, MA 02110-1301, USA.
30 using System.Collections.Generic;
31 using System.ComponentModel;
33 using System.Diagnostics.CodeAnalysis;
39 using System.Text.RegularExpressions;
40 using System.Threading;
41 using System.Threading.Tasks;
43 using System.Windows.Forms;
45 using OpenTween.Api.DataModel;
46 using OpenTween.Connection;
50 public partial class UserInfoDialog : OTBaseForm
52 private TwitterUser displayUser = null!;
53 private CancellationTokenSource? cancellationTokenSource = null;
55 private readonly TweenMain mainForm;
56 private readonly TwitterApi twitterApi;
58 public UserInfoDialog(TweenMain mainForm, TwitterApi twitterApi)
60 this.mainForm = mainForm;
61 this.twitterApi = twitterApi;
63 this.InitializeComponent();
65 // LabelScreenName のフォントを OTBaseForm.GlobalFont に変更
66 this.LabelScreenName.Font = this.ReplaceToGlobalFont(this.LabelScreenName.Font);
69 [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")]
70 private void CancelLoading()
72 CancellationTokenSource? oldTokenSource = null;
75 var newTokenSource = new CancellationTokenSource();
76 oldTokenSource = Interlocked.Exchange(ref this.cancellationTokenSource, newTokenSource);
80 if (oldTokenSource != null)
82 oldTokenSource.Cancel();
83 oldTokenSource.Dispose();
88 public async Task ShowUserAsync(TwitterUser user)
93 if (user == null || user == this.displayUser)
98 var cancellationToken = this.cancellationTokenSource!.Token;
100 this.displayUser = user;
102 this.LabelId.Text = user.IdStr;
103 this.LabelScreenName.Text = user.ScreenName;
104 this.LabelName.Text = user.Name;
105 this.LabelLocation.Text = user.Location ?? "";
106 this.LabelCreatedAt.Text = MyCommon.DateTimeParse(user.CreatedAt).ToLocalTimeString();
109 this.LabelIsProtected.Text = Properties.Resources.Yes;
111 this.LabelIsProtected.Text = Properties.Resources.No;
114 this.LabelIsVerified.Text = Properties.Resources.Yes;
116 this.LabelIsVerified.Text = Properties.Resources.No;
118 var followingUrl = "https://twitter.com/" + user.ScreenName + "/following";
119 this.LinkLabelFollowing.Text = user.FriendsCount.ToString();
120 this.LinkLabelFollowing.Tag = followingUrl;
121 this.ToolTip1.SetToolTip(this.LinkLabelFollowing, followingUrl);
123 var followersUrl = "https://twitter.com/" + user.ScreenName + "/followers";
124 this.LinkLabelFollowers.Text = user.FollowersCount.ToString();
125 this.LinkLabelFollowers.Tag = followersUrl;
126 this.ToolTip1.SetToolTip(this.LinkLabelFollowers, followersUrl);
128 var favoritesUrl = "https://twitter.com/" + user.ScreenName + "/favorites";
129 this.LinkLabelFav.Text = user.FavouritesCount.ToString();
130 this.LinkLabelFav.Tag = favoritesUrl;
131 this.ToolTip1.SetToolTip(this.LinkLabelFav, favoritesUrl);
133 var profileUrl = "https://twitter.com/" + user.ScreenName;
134 this.LinkLabelTweet.Text = user.StatusesCount.ToString();
135 this.LinkLabelTweet.Tag = profileUrl;
136 this.ToolTip1.SetToolTip(this.LinkLabelTweet, profileUrl);
138 if (this.twitterApi.CurrentUserId == user.Id)
140 this.ButtonEdit.Enabled = true;
141 this.ChangeIconToolStripMenuItem.Enabled = true;
142 this.ButtonBlock.Enabled = false;
143 this.ButtonReportSpam.Enabled = false;
144 this.ButtonBlockDestroy.Enabled = false;
148 this.ButtonEdit.Enabled = false;
149 this.ChangeIconToolStripMenuItem.Enabled = false;
150 this.ButtonBlock.Enabled = true;
151 this.ButtonReportSpam.Enabled = true;
152 this.ButtonBlockDestroy.Enabled = true;
155 await Task.WhenAll(new[]
157 this.SetDescriptionAsync(user.Description, user.Entities?.Description, cancellationToken),
158 this.SetRecentStatusAsync(user.Status, cancellationToken),
159 this.SetLinkLabelWebAsync(user.Url, user.Entities?.Url, cancellationToken),
160 this.SetUserImageAsync(user.ProfileImageUrlHttps, cancellationToken),
161 this.LoadFriendshipAsync(user.ScreenName, cancellationToken),
165 private async Task SetDescriptionAsync(string? descriptionText, TwitterEntities? entities, CancellationToken cancellationToken)
167 if (descriptionText != null)
169 var urlEntities = entities?.Urls ?? Array.Empty<TwitterEntityUrl>();
171 foreach (var entity in urlEntities)
173 if (entity.ExpandedUrl == null)
176 entity.ExpandedUrl = await ShortUrl.Instance.ExpandUrlAsync(entity.ExpandedUrl);
179 // user.entities には urls 以外のエンティティが含まれていないため、テキストをもとに生成する
180 var mergedEntities = urlEntities.AsEnumerable<TwitterEntity>()
181 .Concat(TweetExtractor.ExtractHashtagEntities(descriptionText))
182 .Concat(TweetExtractor.ExtractMentionEntities(descriptionText))
183 .Concat(TweetExtractor.ExtractEmojiEntities(descriptionText));
185 var html = TweetFormatter.AutoLinkHtml(descriptionText, mergedEntities);
186 html = this.mainForm.CreateDetailHtml(html);
188 if (cancellationToken.IsCancellationRequested)
191 this.DescriptionBrowser.DocumentText = html;
195 this.DescriptionBrowser.DocumentText = this.mainForm.CreateDetailHtml("");
199 private async Task SetUserImageAsync(string imageUri, CancellationToken cancellationToken)
201 var oldImage = this.UserPicture.Image;
202 this.UserPicture.Image = null;
205 // ProfileImageUrlHttps が null になる場合があるらしい
206 // 参照: https://sourceforge.jp/ticket/browse.php?group_id=6526&tid=33871
207 if (imageUri == null)
210 await this.UserPicture.SetImageFromTask(async () =>
212 var sizeName = Twitter.DecideProfileImageSize(this.UserPicture.Width);
213 var uri = Twitter.CreateProfileImageUrl(imageUri, sizeName);
215 using var imageStream = await Networking.Http.GetStreamAsync(uri)
216 .ConfigureAwait(false);
218 var image = await MemoryImage.CopyFromStreamAsync(imageStream)
219 .ConfigureAwait(false);
221 if (cancellationToken.IsCancellationRequested)
224 throw new OperationCanceledException(cancellationToken);
231 private async Task SetLinkLabelWebAsync(string? uri, TwitterEntities? entities, CancellationToken cancellationToken)
235 var origUrl = entities?.Urls?.FirstOrDefault()?.ExpandedUrl ?? uri;
236 var expandedUrl = await ShortUrl.Instance.ExpandUrlAsync(origUrl);
238 if (cancellationToken.IsCancellationRequested)
241 this.LinkLabelWeb.Text = expandedUrl;
242 this.LinkLabelWeb.Tag = expandedUrl;
243 this.ToolTip1.SetToolTip(this.LinkLabelWeb, expandedUrl);
247 this.LinkLabelWeb.Text = "";
248 this.LinkLabelWeb.Tag = null;
249 this.ToolTip1.SetToolTip(this.LinkLabelWeb, null);
253 private async Task SetRecentStatusAsync(TwitterStatus? status, CancellationToken cancellationToken)
257 var entities = status.MergedEntities;
258 var urlEntities = entities.Urls ?? Array.Empty<TwitterEntityUrl>();
260 foreach (var entity in urlEntities)
261 entity.ExpandedUrl = await ShortUrl.Instance.ExpandUrlAsync(entity.ExpandedUrl ?? entity.Url);
263 var mergedEntities = entities.Concat(TweetExtractor.ExtractEmojiEntities(status.FullText));
265 var html = TweetFormatter.AutoLinkHtml(status.FullText, mergedEntities);
266 html = this.mainForm.CreateDetailHtml(html +
267 " Posted at " + MyCommon.DateTimeParse(status.CreatedAt).ToLocalTimeString() +
268 " via " + status.Source);
270 if (cancellationToken.IsCancellationRequested)
273 this.RecentPostBrowser.DocumentText = html;
277 this.RecentPostBrowser.DocumentText = this.mainForm.CreateDetailHtml(Properties.Resources.ShowUserInfo2);
281 private async Task LoadFriendshipAsync(string screenName, CancellationToken cancellationToken)
283 this.LabelIsFollowing.Text = "";
284 this.LabelIsFollowed.Text = "";
285 this.ButtonFollow.Enabled = false;
286 this.ButtonUnFollow.Enabled = false;
288 if (this.twitterApi.CurrentScreenName == screenName)
291 TwitterFriendship friendship;
294 friendship = await this.twitterApi.FriendshipsShow(this.twitterApi.CurrentScreenName, screenName);
296 catch (WebApiException)
298 this.LabelIsFollowed.Text = Properties.Resources.GetFriendshipInfo6;
299 this.LabelIsFollowing.Text = Properties.Resources.GetFriendshipInfo6;
303 if (cancellationToken.IsCancellationRequested)
306 var isFollowing = friendship.Relationship.Source.Following;
307 var isFollowedBy = friendship.Relationship.Source.FollowedBy;
309 this.LabelIsFollowing.Text = isFollowing
310 ? Properties.Resources.GetFriendshipInfo1
311 : Properties.Resources.GetFriendshipInfo2;
313 this.LabelIsFollowed.Text = isFollowedBy
314 ? Properties.Resources.GetFriendshipInfo3
315 : Properties.Resources.GetFriendshipInfo4;
317 this.ButtonFollow.Enabled = !isFollowing;
318 this.ButtonUnFollow.Enabled = isFollowing;
321 private void ShowUserInfo_Load(object sender, EventArgs e)
323 this.TextBoxName.Location = this.LabelName.Location;
324 this.TextBoxName.Height = this.LabelName.Height;
325 this.TextBoxName.Width = this.LabelName.Width;
326 this.TextBoxName.BackColor = this.mainForm.InputBackColor;
328 this.TextBoxLocation.Location = this.LabelLocation.Location;
329 this.TextBoxLocation.Height = this.LabelLocation.Height;
330 this.TextBoxLocation.Width = this.LabelLocation.Width;
331 this.TextBoxLocation.BackColor = this.mainForm.InputBackColor;
333 this.TextBoxWeb.Location = this.LinkLabelWeb.Location;
334 this.TextBoxWeb.Height = this.LinkLabelWeb.Height;
335 this.TextBoxWeb.Width = this.LinkLabelWeb.Width;
336 this.TextBoxWeb.BackColor = this.mainForm.InputBackColor;
338 this.TextBoxDescription.Location = this.DescriptionBrowser.Location;
339 this.TextBoxDescription.Height = this.DescriptionBrowser.Height;
340 this.TextBoxDescription.Width = this.DescriptionBrowser.Width;
341 this.TextBoxDescription.BackColor = this.mainForm.InputBackColor;
342 this.TextBoxDescription.Multiline = true;
343 this.TextBoxDescription.ScrollBars = ScrollBars.Vertical;
346 private async void LinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
348 var linkLabel = (LinkLabel)sender;
350 var linkUrl = (string)linkLabel.Tag;
354 await MyCommon.OpenInBrowserAsync(this, linkUrl);
357 private async void ButtonFollow_Click(object sender, EventArgs e)
359 using (ControlTransaction.Disabled(this.ButtonFollow))
363 await this.twitterApi.FriendshipsCreate(this.displayUser.ScreenName)
366 catch (WebApiException ex)
368 MessageBox.Show(Properties.Resources.FRMessage2 + ex.Message);
373 MessageBox.Show(Properties.Resources.FRMessage3);
374 this.LabelIsFollowing.Text = Properties.Resources.GetFriendshipInfo1;
375 this.ButtonFollow.Enabled = false;
376 this.ButtonUnFollow.Enabled = true;
379 private async void ButtonUnFollow_Click(object sender, EventArgs e)
382 this.displayUser.ScreenName + Properties.Resources.ButtonUnFollow_ClickText1,
383 Properties.Resources.ButtonUnFollow_ClickText2,
384 MessageBoxButtons.YesNo,
385 MessageBoxIcon.Warning,
386 MessageBoxDefaultButton.Button2) == DialogResult.Yes)
388 using (ControlTransaction.Disabled(this.ButtonUnFollow))
392 await this.twitterApi.FriendshipsDestroy(this.displayUser.ScreenName)
395 catch (WebApiException ex)
397 MessageBox.Show(Properties.Resources.FRMessage2 + ex.Message);
402 MessageBox.Show(Properties.Resources.FRMessage3);
403 this.LabelIsFollowing.Text = Properties.Resources.GetFriendshipInfo2;
404 this.ButtonFollow.Enabled = true;
405 this.ButtonUnFollow.Enabled = false;
409 private void ShowUserInfo_Activated(object sender, EventArgs e)
411 // 画面が他画面の裏に隠れると、アイコン画像が再描画されない問題の対応
412 if (this.UserPicture.Image != null)
413 this.UserPicture.Invalidate(false);
416 private void ShowUserInfo_Shown(object sender, EventArgs e)
417 => this.ButtonClose.Focus();
419 private async void WebBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
421 if (e.Url.AbsoluteUri != "about:blank")
425 // Ctrlを押しながらリンクを開いた場合は、設定と逆の動作をするフラグを true としておく
426 await this.mainForm.OpenUriAsync(e.Url, MyCommon.IsKeyDown(Keys.Control));
430 private void SelectAllToolStripMenuItem_Click(object sender, EventArgs e)
432 var browser = (WebBrowser)this.ContextMenuRecentPostBrowser.SourceControl;
433 browser.Document.ExecCommand("SelectAll", false, null);
436 private void SelectionCopyToolStripMenuItem_Click(object sender, EventArgs e)
438 var browser = (WebBrowser)this.ContextMenuRecentPostBrowser.SourceControl;
439 var selectedText = browser.GetSelectedText();
440 if (selectedText != null)
444 Clipboard.SetDataObject(selectedText, false, 5, 100);
448 MessageBox.Show(ex.Message);
453 private void ContextMenuRecentPostBrowser_Opening(object sender, CancelEventArgs e)
455 var browser = (WebBrowser)this.ContextMenuRecentPostBrowser.SourceControl;
456 var selectedText = browser.GetSelectedText();
458 this.SelectionCopyToolStripMenuItem.Enabled = selectedText != null;
461 private async void LinkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
462 => await MyCommon.OpenInBrowserAsync(this, "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");
464 private async void LinkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
465 => await MyCommon.OpenInBrowserAsync(this, "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");
467 private async void ButtonSearchPosts_Click(object sender, EventArgs e)
468 => await this.mainForm.AddNewTabForUserTimeline(this.displayUser.ScreenName);
470 private async void UserPicture_Click(object sender, EventArgs e)
472 var imageUrl = this.displayUser.ProfileImageUrlHttps;
473 imageUrl = Twitter.CreateProfileImageUrl(imageUrl, "original");
475 await MyCommon.OpenInBrowserAsync(this, imageUrl);
478 private bool isEditing = false;
479 private string buttonEditText = "";
481 private async void ButtonEdit_Click(object sender, EventArgs e)
483 // 自分以外のプロフィールは変更できない
484 if (this.twitterApi.CurrentUserId != this.displayUser.Id)
487 using (ControlTransaction.Disabled(this.ButtonEdit))
491 this.buttonEditText = this.ButtonEdit.Text;
492 this.ButtonEdit.Text = Properties.Resources.UserInfoButtonEdit_ClickText1;
494 this.TextBoxName.Text = this.LabelName.Text;
495 this.TextBoxName.Enabled = true;
496 this.TextBoxName.Visible = true;
497 this.LabelName.Visible = false;
499 this.TextBoxLocation.Text = this.LabelLocation.Text;
500 this.TextBoxLocation.Enabled = true;
501 this.TextBoxLocation.Visible = true;
502 this.LabelLocation.Visible = false;
504 this.TextBoxWeb.Text = this.displayUser.Url;
505 this.TextBoxWeb.Enabled = true;
506 this.TextBoxWeb.Visible = true;
507 this.LinkLabelWeb.Visible = false;
509 this.TextBoxDescription.Text = this.displayUser.Description;
510 this.TextBoxDescription.Enabled = true;
511 this.TextBoxDescription.Visible = true;
512 this.DescriptionBrowser.Visible = false;
514 this.TextBoxName.Focus();
515 this.TextBoxName.Select(this.TextBoxName.Text.Length, 0);
517 this.isEditing = true;
521 Task? showUserTask = null;
523 if (this.TextBoxName.Modified ||
524 this.TextBoxLocation.Modified ||
525 this.TextBoxWeb.Modified ||
526 this.TextBoxDescription.Modified)
530 using var response = await this.twitterApi.AccountUpdateProfile(
531 this.TextBoxName.Text,
532 this.TextBoxWeb.Text,
533 this.TextBoxLocation.Text,
534 this.TextBoxDescription.Text);
536 var user = await response.LoadJsonAsync();
537 showUserTask = this.ShowUserAsync(user);
539 catch (WebApiException ex)
541 MessageBox.Show($"Err:{ex.Message}(AccountUpdateProfile)");
546 this.TextBoxName.Enabled = false;
547 this.TextBoxName.Visible = false;
548 this.LabelName.Visible = true;
550 this.TextBoxLocation.Enabled = false;
551 this.TextBoxLocation.Visible = false;
552 this.LabelLocation.Visible = true;
554 this.TextBoxWeb.Enabled = false;
555 this.TextBoxWeb.Visible = false;
556 this.LinkLabelWeb.Visible = true;
558 this.TextBoxDescription.Enabled = false;
559 this.TextBoxDescription.Visible = false;
560 this.DescriptionBrowser.Visible = true;
562 this.ButtonEdit.Text = this.buttonEditText;
564 this.isEditing = false;
566 if (showUserTask != null)
572 private async Task DoChangeIcon(string filename)
576 var mediaItem = new FileMediaItem(filename);
578 await this.twitterApi.AccountUpdateProfileImage(mediaItem)
581 catch (WebApiException ex)
583 MessageBox.Show("Err:" + ex.Message + Environment.NewLine + Properties.Resources.ChangeIconToolStripMenuItem_ClickText4);
587 MessageBox.Show(Properties.Resources.ChangeIconToolStripMenuItem_ClickText5);
591 var user = await this.twitterApi.UsersShow(this.displayUser.ScreenName);
594 await this.ShowUserAsync(user);
596 catch (WebApiException ex)
598 MessageBox.Show($"Err:{ex.Message}(UsersShow)");
602 private async void ChangeIconToolStripMenuItem_Click(object sender, EventArgs e)
604 this.OpenFileDialogIcon.Filter = Properties.Resources.ChangeIconToolStripMenuItem_ClickText1;
605 this.OpenFileDialogIcon.Title = Properties.Resources.ChangeIconToolStripMenuItem_ClickText2;
606 this.OpenFileDialogIcon.FileName = "";
608 var rslt = this.OpenFileDialogIcon.ShowDialog();
610 if (rslt != DialogResult.OK)
615 var fn = this.OpenFileDialogIcon.FileName;
616 if (this.IsValidIconFile(new FileInfo(fn)))
618 await this.DoChangeIcon(fn);
622 MessageBox.Show(Properties.Resources.ChangeIconToolStripMenuItem_ClickText6);
626 private async void ButtonBlock_Click(object sender, EventArgs e)
629 this.displayUser.ScreenName + Properties.Resources.ButtonBlock_ClickText1,
630 Properties.Resources.ButtonBlock_ClickText2,
631 MessageBoxButtons.YesNo,
632 MessageBoxIcon.Warning,
633 MessageBoxDefaultButton.Button2) == DialogResult.Yes)
635 using (ControlTransaction.Disabled(this.ButtonBlock))
639 await this.twitterApi.BlocksCreate(this.displayUser.ScreenName)
642 catch (WebApiException ex)
644 MessageBox.Show("Err:" + ex.Message + Environment.NewLine + Properties.Resources.ButtonBlock_ClickText3);
648 MessageBox.Show(Properties.Resources.ButtonBlock_ClickText4);
653 private async void ButtonReportSpam_Click(object sender, EventArgs e)
656 this.displayUser.ScreenName + Properties.Resources.ButtonReportSpam_ClickText1,
657 Properties.Resources.ButtonReportSpam_ClickText2,
658 MessageBoxButtons.YesNo,
659 MessageBoxIcon.Warning,
660 MessageBoxDefaultButton.Button2) == DialogResult.Yes)
662 using (ControlTransaction.Disabled(this.ButtonReportSpam))
666 await this.twitterApi.UsersReportSpam(this.displayUser.ScreenName)
669 catch (WebApiException ex)
671 MessageBox.Show("Err:" + ex.Message + Environment.NewLine + Properties.Resources.ButtonReportSpam_ClickText3);
675 MessageBox.Show(Properties.Resources.ButtonReportSpam_ClickText4);
680 private async void ButtonBlockDestroy_Click(object sender, EventArgs e)
683 this.displayUser.ScreenName + Properties.Resources.ButtonBlockDestroy_ClickText1,
684 Properties.Resources.ButtonBlockDestroy_ClickText2,
685 MessageBoxButtons.YesNo,
686 MessageBoxIcon.Warning,
687 MessageBoxDefaultButton.Button2) == DialogResult.Yes)
689 using (ControlTransaction.Disabled(this.ButtonBlockDestroy))
693 await this.twitterApi.BlocksDestroy(this.displayUser.ScreenName)
696 catch (WebApiException ex)
698 MessageBox.Show("Err:" + ex.Message + Environment.NewLine + Properties.Resources.ButtonBlockDestroy_ClickText3);
702 MessageBox.Show(Properties.Resources.ButtonBlockDestroy_ClickText4);
707 private bool IsValidExtension(string ext)
709 var allowedExtensions = new[] { ".jpg", ".jpeg", ".png", ".gif" };
711 return allowedExtensions.Contains(ext, StringComparer.InvariantCultureIgnoreCase);
714 private bool IsValidIconFile(FileInfo info)
716 return this.IsValidExtension(info.Extension) &&
717 info.Length < 700 * 1024 &&
718 !MyCommon.IsAnimatedGif(info.FullName);
721 private void ShowUserInfo_DragEnter(object sender, DragEventArgs e)
723 if (e.Data.GetDataPresent(DataFormats.FileDrop) &&
724 !e.Data.GetDataPresent(DataFormats.Html, false)) // WebBrowserコントロールからの絵文字画像D&Dは弾く
726 var files = (string[])e.Data.GetData(DataFormats.FileDrop, false);
727 if (files.Length != 1)
730 var finfo = new FileInfo(files[0]);
731 if (this.IsValidIconFile(finfo))
733 e.Effect = DragDropEffects.Copy;
738 private async void ShowUserInfo_DragDrop(object sender, DragEventArgs e)
740 if (e.Data.GetDataPresent(DataFormats.FileDrop) &&
741 !e.Data.GetDataPresent(DataFormats.Html, false)) // WebBrowserコントロールからの絵文字画像D&Dは弾く
743 var ret = MessageBox.Show(
745 Properties.Resources.ChangeIconToolStripMenuItem_Confirm,
746 ApplicationSettings.ApplicationName,
747 MessageBoxButtons.OKCancel,
748 MessageBoxIcon.Question);
749 if (ret != DialogResult.OK)
752 var filename = ((string[])e.Data.GetData(DataFormats.FileDrop, false))[0];
753 await this.DoChangeIcon(filename);
757 protected override void Dispose(bool disposing)
761 var cts = this.cancellationTokenSource;
765 var oldImage = this.UserPicture.Image;
766 this.UserPicture.Image = null;
769 this.components?.Dispose();
772 base.Dispose(disposing);